@officexapp/vidfarm-devcli 0.21.29 → 0.21.31
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/vidfarm/SKILL.md +2 -0
- package/.agents/skills/vidfarm/recipes/cutout-graphics-for-explainers.md +18 -4
- package/.agents/skills/vidfarm/references/assets-and-sourcing.md +17 -0
- package/.agents/skills/vidfarm/references/automation-and-local-dev.md +6 -3
- package/.agents/skills/vidfarm/references/editor-workflows.md +1 -1
- package/.agents/skills/vidfarm/references/primitives.md +80 -1
- package/SKILL.director.md +124 -9
- package/SKILL.md +2 -1
- package/dist/src/cli.js +192 -11
- package/dist/src/devcli/doctor.js +13 -0
- package/dist/src/devcli/handoff.js +6 -2
- package/dist/src/devcli/hyperframes-cli.js +12 -0
- package/dist/src/devcli/sticker-pack.js +196 -2
- package/dist/src/devcli/studio-brand.js +196 -0
- package/package.json +5 -1
package/SKILL.director.md
CHANGED
|
@@ -210,6 +210,7 @@ Present both harnesses to the director, recommend (A) unless they've asked for p
|
|
|
210
210
|
- **Stickers are usually animated, not pasted.** Once placed, animate each one with `vidfarm keyframes` presets (`pop-in`, `float`, `shake`, `grow`, `slide-in-left`, `drift`) — that's HTML/CSS canvas motion, deterministic, free, and identical in preview and render. Layer moves up (pop-in, then idle float) for real life. See `references/editor-workflows.md` → "Cutout graphics for explainers".
|
|
211
211
|
- **A sticker can carry its OWN motion too.** A *moving* subject has no single bounding box, so it isn't a PNG: key the clip with `vidfarm remove-greenscreen <video>` → transparent WebM (browser/editor-playable, the right choice on a composition).
|
|
212
212
|
- **The plate must be a color the ART DOESN'T USE — green is a default, not a law.** A chroma key removes exactly ONE color, so a green plate under green artwork (leaves, frogs, plants, money, an "eco" icon set) keys holes straight through the stickers. `sticker-pack`/`cutout` handle this for you in two ways, and you should still say it out loud when it matters: **(a)** when generating, they read the subject and move the plate off any hue it mentions — green → magenta (`#FF00FF`) → blue (`#0047BB`) → black → white — and print which plate they picked and why; **(b)** when splitting a sheet you already have, they **detect the plate from the sheet's four corners**, so a red/purple/blue sheet handed back from a web generator just works. Pin it yourself with `--key-color "#FF00FF"` / `--preset magenta` (that disables the auto-pick), or `--no-auto-key` to force plain green. If a pack's palette collides with *every* standard plate, split it into two sheets on two different plates rather than fighting the key.
|
|
213
|
+
- **The ART must be CLOSED and SOLIDLY FILLED — this is the other half of surviving the key, and the #1 way stickers come back broken.** Ask an image model for "icons on a green plate" and it will happily draw **outline art**: a colored stroke with the shape's interior left as bare plate. It looks perfect on the sheet, and after the key each sticker is a **rim floating around a see-through hole** (an apple-shaped outline with nothing inside it). Same outcome from a *near-plate* fill (the keyer works on tolerance, not exact match), a translucent/glassy/glowing material, or a soft glow fading into the plate. **You cannot key those pixels back — it has to be in the prompt:** *"every object is a closed, solidly filled shape; outlines must enclose an opaque fill of a different color; no outline-only or hollow art; nothing on the art in the plate color or any near-shade of it; fully opaque, no translucency, glow or drop shadow."* `cutout --generate`, `sticker-pack --generate`, `handoff image` and the `create-overlay` primitive **append that clause for you** with the chosen plate hex — write it yourself only when you prompt a generator directly. After the key, both commands report per-item `hole_pct`/`hollow` (console `⚠ N% hollow`, `--json`, `stickers.json`) — a ring or picture frame reads the same way, so it **warns, never blocks**. Flagged and it shouldn't be? Re-generate with the fill clause; a *near*-plate fill can sometimes be rescued with a lower `--tolerance`; one stubborn item can be lifted with `vidfarm mask --crop …` (ONNX matting ignores fill color).
|
|
213
214
|
- **Transparent GIF is supported, for GIF-only surfaces.** `vidfarm sticker-pack … --output-format gif` (stills) and `vidfarm remove-greenscreen <video> --gif` (animated) emit transparent GIFs. GIF alpha is **1-bit**, so edges go hard — fine for chat/forum/Notion sticker surfaces, worse than PNG/WebP/WebM for compositing on a timeline. Prefer PNG/WebP/WebM unless the destination only eats GIF.
|
|
214
215
|
|
|
215
216
|
**Explainer house style — the defaults to build with unless told otherwise.** **White background / light mode** (plain white stage, no gradients, no dark mode, no photo backdrop), **kinetic word-by-word captions** in dark ink on the light stage (`vidfarm captions generate --style word-pop --color "#111111" --active-color "#7C3AED" --background-style plain` — skip outlines/shadows, they're only needed over busy footage), and **female TTS narration** (`vidfarm tts --voice coral` on OpenAI — `nova` for energy, `sage` for calm; `Kore`/`Leda` on Gemini; any ElevenLabs voice via `vidfarm voices`). **Keep it clean and simple** — one idea on screen at a time, two or three cutouts per beat, one accent color, one font, lots of white space; remove before you add. **Illustrations default to simplicity**: flat vector, simple shapes, minimal detail, 2–3 flat colors, no baked-in text — simple art keys cleanly, trims tight, and stays on-style across the whole cast. State the defaults once so the director can override any of them. Full detail: recipe `recipes/cutout-graphics-for-explainers.md` (“House style — the explainer defaults”).
|
|
@@ -317,6 +318,7 @@ Choose the narrowest path that satisfies the request.
|
|
|
317
318
|
3. If the task is “change this video,” read `references/editor-workflows.md`.
|
|
318
319
|
4. If the task is “find footage” or “use our existing assets,” read `references/assets-and-sourcing.md`.
|
|
319
320
|
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`.
|
|
321
|
+
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`.
|
|
320
322
|
5. If the task is scripted, local, CI-driven, or `vidfarm serve`-based, read `references/automation-and-local-dev.md`.
|
|
321
323
|
6. If the task explicitly asks for a primitive or needs specialized generation/transcription work, read `references/primitives.md`.
|
|
322
324
|
7. If the task is the MARKETPLACE (ordering videos from specialist agents): browsing is web-only for paying customers — send the human to https://vidfarm.cc/marketplace, never render it locally. Placing/listing orders is the thin REST wrapper in `references/core-workflows.md` (§ Marketplace); anything deeper on a gig (inbox, proofs, payouts) needs the external Dollar Platoon skill — `npx skills add https://github.com/OfficeXApp/dollarplatoon-skill` — the same way FlockPoster work beyond scheduling needs `npx skills add https://github.com/OfficeXApp/flockposter-skill`.
|
|
@@ -1247,7 +1249,7 @@ Beyond the Ken Burns / transition / animated-caption presets, the copilot can ha
|
|
|
1247
1249
|
|
|
1248
1250
|
**Make the sticker (`vidfarm cutout`).** Local, free, ffmpeg-only, image-only. `vidfarm cutout --generate "<subject>"` AI-generates on a matching plate then keys+trims (only the generation is billed); `vidfarm cutout <file|url>` keys+trims a graphic you already have for $0. Because the output is trimmed tight, its on-frame **width % maps directly to how big the subject reads** — no invisible padding skewing the layout. Knobs: `--preset`/`--key-color` (match the plate), `--pad <px>` (transparent breathing room), `--alpha-threshold <0..255>` (trim faint haloed edges), `--output-format webp`, `--no-trim`. A *moving* subject has no single bounding box → key it as a clip with `vidfarm remove-greenscreen <video>` (→ transparent WebM) instead.
|
|
1249
1251
|
|
|
1250
|
-
**Make a whole PACK at once (`vidfarm sticker-pack`).** When the scene needs a *set* — props, icons, a cast, plus any backdrops — don't run `cutout` N times. Generate ONE greenscreen sheet holding every item and split it locally: `vidfarm sticker-pack --generate "<theme>" --items "a,b,c" --out-dir ./stickers` (one billed image job for the set), or `vidfarm sticker-pack ./sheet.png` for $0 on a sheet you already have. It keys the plate once, **segments the sheet's alpha channel to find each item automatically** (no hand-measured crop rects), trims each to its true box, and writes `stickers.json`. `--dry-run` to inspect the boxes; `--gap` to fix items that merged (lower) or split (raise). **Item size is unbounded** — a full-frame landscape/skyline/backdrop is as legitimate a sticker as a small icon, and belongs in the same sheet so it shares the cast's style. Recipe: `recipes/cutout-graphics-for-explainers.md` → "A sticker pack".
|
|
1252
|
+
**Make a whole PACK at once (`vidfarm sticker-pack`).** When the scene needs a *set* — props, icons, a cast, plus any backdrops — don't run `cutout` N times. Generate ONE greenscreen sheet holding every item and split it locally: `vidfarm sticker-pack --generate "<theme>" --items "a,b,c" --out-dir ./stickers` (one billed image job for the set), or `vidfarm sticker-pack ./sheet.png` for $0 on a sheet you already have. It keys the plate once, **segments the sheet's alpha channel to find each item automatically** (no hand-measured crop rects), trims each to its true box, and writes `stickers.json`. `--dry-run` to inspect the boxes; `--gap` to fix items that merged (lower) or split (raise). **Ask for solidly filled art** — outline-only/hollow shapes (or fills in a near-plate shade) get their interiors keyed away and composite as rims around transparent holes; the generation prompt says so automatically, and each item reports `⚠ N% hollow` / `hole_pct` after the key so you catch it before placing. **Item size is unbounded** — a full-frame landscape/skyline/backdrop is as legitimate a sticker as a small icon, and belongs in the same sheet so it shares the cast's style. Recipe: `recipes/cutout-graphics-for-explainers.md` → "A sticker pack".
|
|
1251
1253
|
|
|
1252
1254
|
**Sticker formats.** Still sticker → **PNG** (or `--output-format webp` for smaller files). Sticker whose own artwork moves → **transparent WebM** via `vidfarm remove-greenscreen <video>` (ProRes `.mov` is the local fallback; `--cloud` always returns WebM). Sticker destined for a **GIF-only surface** (chat, forum, Notion, a shareable pack) → `--output-format gif` on `sticker-pack`, or `vidfarm remove-greenscreen <video> --gif` for an animated one; GIF alpha is 1-bit, so edges harden and soft shadows vanish — never the choice for compositing on a timeline.
|
|
1253
1255
|
|
|
@@ -1542,6 +1544,23 @@ Both are async primitive jobs — poll `GET /api/v1/primitives/jobs/:jobId` unti
|
|
|
1542
1544
|
|
|
1543
1545
|
**Don't reach for this when the real goal is clips.** If the user wants short clips mined out of a long video, `POST /raws/scan` with `source_url` already downloads the source for you as part of the hunt (below) — a separate download call is wasted spend.
|
|
1544
1546
|
|
|
1547
|
+
## Recycle a Reddit or X source into content ("tweet to TikTok", "Reddit to TikTok")
|
|
1548
|
+
|
|
1549
|
+
When the source isn't a video file but a **conversation** — a Reddit thread and its comments, a subreddit's front page, an X thread and its replies, an account's timeline — the download routes are the wrong tool. Use `vidfarm recycle <source>` (devcli) or `POST /api/v1/primitives/social/recycle` (alias `/recycle-social`), which **decomposes** the source into JSON you can remix:
|
|
1550
|
+
|
|
1551
|
+
| Paste this | You get back |
|
|
1552
|
+
| --- | --- |
|
|
1553
|
+
| `reddit.com/r/<sub>/comments/<id>/...` | the post + its whole comment tree |
|
|
1554
|
+
| `reddit.com/r/<sub>` or `r/<sub>` | that subreddit's threads |
|
|
1555
|
+
| `x.com/<user>/status/<id>` | the tweet + self-thread + replies |
|
|
1556
|
+
| `x.com/<user>` or `@<user>` | that account's posts, pinned first |
|
|
1557
|
+
|
|
1558
|
+
Every item carries text, author + `avatar_url`, timestamps, permalink, engagement stats, and **media URLs** (X video resolves to the top-bitrate MP4). It never summarizes or ranks — you read `items[]` and choose the hook, the punchline comment, the stat worth a card. `max_records` is your spend ceiling; `nextCursor` resumes. Paid plans only.
|
|
1559
|
+
|
|
1560
|
+
Under the hood it brokers the **reddit-lead-gen** and **x-lead-gen** OfficeX apps rather than holding Reddit/X keys itself — so it's a job wrapping a job, and the primitive waits out the upstream job for you. Full payload/response reference in `references/primitives.md` → *Primitive: social/recycle*.
|
|
1561
|
+
|
|
1562
|
+
Pipe it forward: any `media[].url` goes straight into a layer or through `videos/download`; `profile.avatar_url` makes the "who said this" badge. **Recycled text is source material, not a script** — rewrite it to the hook/loop/payoff standard instead of pasting a comment thread on screen.
|
|
1563
|
+
|
|
1545
1564
|
## Public raws catalog — browse BY CATEGORY (check here first)
|
|
1546
1565
|
|
|
1547
1566
|
Before you hunt footage and long before you generate it, check what the platform **already has**. The public raws catalog is a curated, pre-tagged, free-to-use pool of short clips, organised into **categories** (shelves) — and browsing it by category is one of the highest-leverage moves available to you, for two reasons:
|
|
@@ -1908,9 +1927,9 @@ The licensed harness also carries the **generative build workflow** guidance (ch
|
|
|
1908
1927
|
| `vidfarm inpaint <image> --mask <png> --prompt "…" [--region "label=…"] [--ref …] [--out <f>]` | `POST /api/v1/primitives/images/inpaint` (polls job) | masked image EDIT — replace ONLY the transparent-mask region, keep everything else (devcli twin of the /inpaint page) |
|
|
1909
1928
|
| `vidfarm create-overlay "<subject>" [--key-color #00FF00] [--aspect-ratio 1:1] [--place <dir>] [--out <f>]` | `POST /api/v1/primitives/images/create-overlay` (polls job) | **Vox-style** transparent OVERLAY — AI image on a forced key-color background, chroma-keyed out in one job → ready-to-composite transparent PNG |
|
|
1910
1929
|
| `vidfarm remove-greenscreen <image\|video> [--preset green\|blue\|white\|black\|digital-green\|magenta] [--key-color #00FF00] [--tolerance 0.3] [--local] [--gif] [--out <f>]` | `POST /api/v1/primitives/remove-greenscreen` (polls job) | chroma-key a FLAT solid background → transparent PNG/WebP (image) or WebM/VP9-alpha (video); auto-detects media kind. `--local` runs it FREE in-process (sharp/ffmpeg, no wallet); default cloud is billed at real compute × 1.2. **`--gif` writes a transparent GIF instead** (ANIMATED for a clip; `--gif-fps`/`--gif-width`/`--gif-alpha`) — local-only, 1-bit alpha, for GIF-only sticker surfaces; prefer PNG/WebP/WebM for compositing. Aliases: `greenscreen`, `remove-background-greenscreen`. |
|
|
1911
|
-
| `vidfarm cutout <image\|url> [--generate "<prompt>"] [--preset green] [--pad <px>] [--alpha-threshold <n>] [--no-trim] [--output-format png\|webp] [--out <f>]` | **local, free, ffmpeg-only** (no job) — key + `alphaextract`/`cropdetect` trim | **The transparent explainer-STICKER maker.** Keys out the flat plate **and then shrinks the canvas to the cutout's true min width/height** (a 1024² mostly-empty plate → a snug sticker whose pixel size IS the subject) so you can scale/position it precisely. `--generate` AI-generates the graphic first on a matching chroma plate (that step is the billed image primitive), then keys+trims in one shot; without it, keys+trims a file/url you already have. **IMAGE-only** (a moving subject has no single bounding box — key a clip with `remove-greenscreen`). Prefer this over `create-overlay` locally: same idea, but free and auto-trimmed. `--pad` keeps transparent breathing room; `--json` reports final `width`/`height`/`area_reduced_pct
|
|
1930
|
+
| `vidfarm cutout <image\|url> [--generate "<prompt>"] [--preset green] [--pad <px>] [--alpha-threshold <n>] [--no-trim] [--output-format png\|webp] [--out <f>]` | **local, free, ffmpeg-only** (no job) — key + `alphaextract`/`cropdetect` trim | **The transparent explainer-STICKER maker.** Keys out the flat plate **and then shrinks the canvas to the cutout's true min width/height** (a 1024² mostly-empty plate → a snug sticker whose pixel size IS the subject) so you can scale/position it precisely. `--generate` AI-generates the graphic first on a matching chroma plate (that step is the billed image primitive), then keys+trims in one shot; without it, keys+trims a file/url you already have. **IMAGE-only** (a moving subject has no single bounding box — key a clip with `remove-greenscreen`). Prefer this over `create-overlay` locally: same idea, but free and auto-trimmed. `--pad` keeps transparent breathing room; `--json` reports final `width`/`height`/`area_reduced_pct`, plus `hole_pct`/`hollow` — the "the key ate the fill" check (outline-only art keys into a rim around a transparent hole; `--generate` prompts against it automatically, and the console prints a `Hollow:` warning with the fix). Alias: `sticker`. See recipe `cutout-graphics-for-explainers.md`. |
|
|
1912
1931
|
| `vidfarm mask <image\|url> [--crop x,y,w,h] [--flat <hex>] [--pad <px>] [--alpha-threshold <n>] [--no-trim] [--output-format png\|webp] [--keep-region <f>] [--out <f>]` | **local, free** (no job) — ffmpeg crop + ONNX matting (or ffmpeg chroma-key) + `cropdetect` trim | **Lift an illustration OUT of an image you already have** (infographic / poster / marketing graphic / brand sheet / screenshot) → snug transparent PNG, the same reusable explainer sticker `cutout` makes but with **$0 and zero AI generation** — the cost-saving move whenever source art exists. `--crop x,y,w,h` (pixels **or** %) isolates ONE element from a multi-illustration source before masking (re-run with different rects to grab each). Background removed by **local ONNX matting** (any/busy background) by default, or **`--flat <hexcolor>`** chroma-keys a solid fill for crisper edges (an infographic's cream/white paper); then trims to the subject's true min width/height. **IMAGE-only** (matte a clip with `remove-background`). Aliases: `isolate`, `extract`. See recipe `cutout-graphics-for-explainers.md` → "Mask from an image you already have". |
|
|
1913
|
-
| `vidfarm sticker-pack [sheet\|url] [--generate "<theme>"] [--items "a,b,c"] [--count <n>] [--dry-run] [--gap <pct>] [--min-area <pct>] [--output-format png\|webp\|gif] [--out-dir <d>]` | **local, free, ffmpeg-only** (no job; only `--generate` bills, ONCE for the whole set) — key + alpha-channel segmentation + per-item trim | **The STICKER-PACK maker — the answer whenever a director asks for "a sticker pack" / prop set / icon set.** A pack is ONE greenscreen sheet holding every item, keyed once and then masked apart: 1/N the cost of N `cutout` calls, and the only way a cast stays on-style. Finds each item **automatically** by segmenting the keyed sheet's alpha into connected islands — no hand-measured `--crop` rects — and writes one snug transparent file per item (named from `--items`, reading order) plus a `stickers.json` manifest. `--dry-run` prints the detected boxes first; `--gap` merges (lower) or splits (raise) items that came out joined/broken; items have **no maximum size** — a full-frame landscape/backdrop is as valid a sticker as a 3% icon. **Plate color is chosen for you:** when generating it reads the subject and moves the plate off any hue the art uses (green → magenta → blue → black → white — a pack of leaves/frogs/money on GREEN would key holes through the art), and when splitting an existing sheet it DETECTS the plate from the sheet's four corners, so a red/purple sheet handed back from a web tool just works. Pin it with `--key-color`/`--preset`, or `--no-auto-key` for plain green. `--output-format gif` emits 1-bit-alpha GIFs for GIF-only surfaces. IMAGE-only. Aliases: `stickers`, `sticker-sheet`. See recipe `cutout-graphics-for-explainers.md` → "A sticker pack". |
|
|
1932
|
+
| `vidfarm sticker-pack [sheet\|url] [--generate "<theme>"] [--items "a,b,c"] [--count <n>] [--dry-run] [--gap <pct>] [--min-area <pct>] [--output-format png\|webp\|gif] [--out-dir <d>]` | **local, free, ffmpeg-only** (no job; only `--generate` bills, ONCE for the whole set) — key + alpha-channel segmentation + per-item trim | **The STICKER-PACK maker — the answer whenever a director asks for "a sticker pack" / prop set / icon set.** A pack is ONE greenscreen sheet holding every item, keyed once and then masked apart: 1/N the cost of N `cutout` calls, and the only way a cast stays on-style. Finds each item **automatically** by segmenting the keyed sheet's alpha into connected islands — no hand-measured `--crop` rects — and writes one snug transparent file per item (named from `--items`, reading order) plus a `stickers.json` manifest. `--dry-run` prints the detected boxes first; `--gap` merges (lower) or splits (raise) items that came out joined/broken; items have **no maximum size** — a full-frame landscape/backdrop is as valid a sticker as a 3% icon. **Plate color is chosen for you:** when generating it reads the subject and moves the plate off any hue the art uses (green → magenta → blue → black → white — a pack of leaves/frogs/money on GREEN would key holes through the art), and when splitting an existing sheet it DETECTS the plate from the sheet's four corners, so a red/purple sheet handed back from a web tool just works. Pin it with `--key-color`/`--preset`, or `--no-auto-key` for plain green. **The ART is made key-safe too:** the generation prompt is auto-appended with "closed, solidly filled shapes, no outline-only/hollow art, nothing in the plate hue or a near-shade, fully opaque, no glow/translucency" — the fix for stickers that come back as a rim around a transparent hole — and after keying each item reports `holes`/`hole_pct`/`hollow` (console `⚠ N% hollow` at ≥20%, plus `--json` and `stickers.json`). It **warns, never blocks** (a ring/frame/donut reads identically); re-generate with the fill clause, or lift that one item with `vidfarm mask --crop …`. `--output-format gif` emits 1-bit-alpha GIFs for GIF-only surfaces. IMAGE-only. Aliases: `stickers`, `sticker-sheet`. See recipe `cutout-graphics-for-explainers.md` → "A sticker pack". |
|
|
1914
1933
|
| `vidfarm tts "…" [--style "…"] [--voice <v>] [--out <file>]` | (LOCAL-FIRST: your own OPENAI/GEMINI/OPENROUTER_API_KEY → audio file on disk; `--cloud` = `POST /api/v1/primitives/audio/speech` + poll, ElevenLabs on the platform key by default, `--own-key` for yours) | text → narration audio; `--cloud --voice <voice_id>` picks an ElevenLabs voice |
|
|
1915
1934
|
| `vidfarm music "<prompt>" [--length <sec>] [--out <f>] [--own-key]` | `POST /api/v1/primitives/music/generate` (polls job) | prompt → music track (ElevenLabs; platform key + wallet by default, `--own-key` for yours) |
|
|
1916
1935
|
| `vidfarm voices [--own-key] [--limit N]` | `GET /api/v1/primitives/audio/voices` | list ElevenLabs voices (voice_id/name/labels) for `tts --voice`; default a voice + tell the user they can choose |
|
|
@@ -1939,7 +1958,7 @@ The licensed harness also carries the **generative build workflow** guidance (ch
|
|
|
1939
1958
|
| `vidfarm whoami` | `GET /api/v1/user/me` | who am I (also prints the active cost mode) |
|
|
1940
1959
|
| `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 |
|
|
1941
1960
|
| `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`. |
|
|
1942
|
-
| `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) and carries that `--key-color` into the follow-up. `--single` for one subject. |
|
|
1961
|
+
| `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 the **key-safe fill rules** (closed solidly-filled shapes, no outline-only/hollow art, nothing in a near-plate shade, fully opaque) so the sheet doesn't come back as rims around holes, and carries that `--key-color` into the follow-up. `--single` for one subject. |
|
|
1943
1962
|
| `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. |
|
|
1944
1963
|
| `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`. |
|
|
1945
1964
|
| `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` |
|
|
@@ -1948,6 +1967,7 @@ The licensed harness also carries the **generative build workflow** guidance (ch
|
|
|
1948
1967
|
| `vidfarm download <url> [dest]` | (streams any URL to disk) | download media from a **direct** media URL. Free — no plan, no job |
|
|
1949
1968
|
| `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` |
|
|
1950
1969
|
| `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` |
|
|
1970
|
+
| `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` |
|
|
1951
1971
|
|
|
1952
1972
|
> **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.
|
|
1953
1973
|
| `vidfarm files [--folder <path>]` | `GET /api/v1/user/me/attachments` | list My Files assets + folders |
|
|
@@ -2059,6 +2079,8 @@ vidfarm doctor # ✓/⚠/✗ for node, ffmpeg, hy
|
|
|
2059
2079
|
- **`ffmpeg`** — the media engine the devcli drives for every local media op: `remove-greenscreen --local` (chroma-key → transparent PNG/WebP/WebM, ProRes fallback where the local libvpx can't do WebM alpha), STT/caption demux, `raws scan` clip cutting, `stills`, audio trims. **Hard requirement** — `vidfarm doctor` exits non-zero without it.
|
|
2060
2080
|
- **`hyperframes`** — **Vidfarm's own render/animation engine, open-source under a whitelabel.** *Vidfarm renders ARE hyperframes renders.* The devcli bundles it and re-exposes everything it does locally as **`vidfarm hf <subcommand>`** — `vidfarm hf render <dir> -o out.mp4`, `capture`, `validate`, `preview`, `doctor`, plus the ONNX `remove-background` matting, Kokoro TTS, and Whisper STT engines the `tts`/`stt`/`remove-background` commands ride. Installing it standalone makes these run **natively** instead of a slower `npx -y hyperframes` fallback (which `vidfarm doctor` will warn about).
|
|
2061
2081
|
|
|
2082
|
+
**The local studio UI is whitelabeled automatically.** `hyperframes preview` (and `vidfarm hf preview`) serves a studio SPA whose stock shell paints an upstream "HeyGen · HyperFrames" header logo and a "HyperFrames Studio" tab title. Every devcli hyperframes spawn — and `vidfarm doctor` — idempotently patches that shell in place (`src/devcli/studio-brand.ts`) so the header reads **VidFarm**, the tab title is **VidFarm Studio**, and the product name in the studio's own copy (lint panel, feedback prompt, storyboard/agent prompts, clipboard writes) is rewritten. `.hyperframes/` paths and `data-hyperframes-*` DOM hooks are preserved verbatim — they name real files and hooks — and CLI verbs map to their twins (`hyperframes render` → `vidfarm render`). A fresh `npm install` restores the stock shell; the next devcli command (or `vidfarm doctor`) re-applies it. If a director ever screenshots upstream branding, run `vidfarm doctor`.
|
|
2083
|
+
|
|
2062
2084
|
**Treat `hyperframes` as Vidfarm** (it is — just whitelabeled): never point it at an external HeyGen/vendor account, publish service, or telemetry endpoint. Keep `HYPERFRAMES_SKIP_SKILLS=1` + `HYPERFRAMES_NO_TELEMETRY=1` set (the devcli sets these for its children); do not run `hyperframes auth`/`cloud`/`publish`/`play`/`feedback` — Vidfarm's own render/share/telemetry surfaces replace all of them. Everything else `hyperframes` can do locally is fair game and encouraged.
|
|
2063
2085
|
|
|
2064
2086
|
## Local dev loop (`vidfarm serve`)
|
|
@@ -2223,7 +2245,7 @@ curl -X POST "$VIDFARM_BASE/api/v1/primitives/images/remove-background" \
|
|
|
2223
2245
|
|
|
2224
2246
|
- `POST /api/v1/primitives/images/create-overlay` (flat alias: `POST /api/v1/primitives/create-media-overlay`)
|
|
2225
2247
|
- Body: `{ "tracer": "...", "payload": { "prompt": "a cartoon rocket ship, flat vector illustration", "provider"?: "...", "model"?: "...", "prompt_attachments"?: ["https://..."], "aspect_ratio"?: "1:1", "image_size"?: "1K"|"2K"|"4K", "key_color"?: "#00FF00", "tolerance"?: 0.3, "softness"?: 0.1, "despill"?: true, "output_format"?: "png"|"webp" }, "webhook_url"?: "..." }`
|
|
2226
|
-
- Just describe the **subject** in `prompt` — do NOT describe the background; the primitive appends the flat key-color background requirement for you.
|
|
2248
|
+
- Just describe the **subject** in `prompt` — do NOT describe the background; the primitive appends the flat key-color background requirement for you, **and** the key-safe *artwork* requirement (closed solidly-filled shapes, no outline-only/hollow art, nothing on the subject in the key hue or a near-shade, fully opaque, no glow/translucency). That second clause is what stops the classic failure: outline art whose interior is bare plate keys into a **rim around a transparent hole**. If you build the prompt yourself for `images/generate` instead of using this primitive, write that clause in by hand.
|
|
2227
2249
|
- `key_color` lets you key against something other than green if your subject is itself green-heavy (e.g. key against `#FF00FF` magenta for a green frog).
|
|
2228
2250
|
- The chroma-key params (`tolerance`/`softness`/`despill`) behave exactly as in `image_remove_background_greenscreen`.
|
|
2229
2251
|
- Response: `primary_file_url` is the finished transparent overlay; `greenscreen_source_url` is the raw pre-key frame (kept so you can re-key at a different tolerance without paying for another generation).
|
|
@@ -2324,6 +2346,85 @@ curl -X POST "$VIDFARM_BASE/api/v1/primitives/audio/download" \
|
|
|
2324
2346
|
-d '{"tracer": "demo-download-audio", "payload": {"source_url": "https://www.youtube.com/watch?v=example"}}'
|
|
2325
2347
|
```
|
|
2326
2348
|
|
|
2349
|
+
## Primitive: social/recycle
|
|
2350
|
+
|
|
2351
|
+
**"Tweet to TikTok" and "Reddit to TikTok" live here.** The text-and-thread sibling of `videos/download`: point it at a Reddit or X/Twitter source and it **decomposes** that source into reusable JSON — the post text, the comment/reply thread, every image/video media URL, the author's profile pic and follower count, and the engagement stats — so YOU decide what to recycle into a new video. It deliberately does **not** summarize, rank, score, or filter. It dumps the data back raw.
|
|
2352
|
+
|
|
2353
|
+
**Vidfarm does not hold Reddit/X vendor keys.** This primitive is a thin broker over the two OfficeX apps that already own that integration — **reddit-lead-gen** and **x-lead-gen** — called through their public REST job API. They own the vendor keys, retries, rate-limit budget, auto-pagination, and 90-day result storage; vidfarm owns target resolution, normalization, and the wallet charge. Both are async job APIs, so a recycle is **a job wrapping a job** — but the nesting is invisible: this primitive polls upstream to completion server-side and only resolves when the data is in hand, exactly like the GhostCut leg of `videos/remove-captions`. You poll `GET /api/v1/primitives/jobs/:jobId` like any other primitive.
|
|
2354
|
+
|
|
2355
|
+
- `POST /api/v1/primitives/social/recycle` (alias: `POST /api/v1/primitives/recycle-social`)
|
|
2356
|
+
- Body: `{ "tracer": "...", "payload": { "source_url": "https://..." }, "webhook_url"?: "..." }`
|
|
2357
|
+
|
|
2358
|
+
### The four shapes
|
|
2359
|
+
|
|
2360
|
+
| You pass | Mode (auto-detected) | You get |
|
|
2361
|
+
| --- | --- | --- |
|
|
2362
|
+
| `https://reddit.com/r/<sub>/comments/<id>/...` | `reddit_thread` | the post + its comment tree, flattened in reading order |
|
|
2363
|
+
| `https://reddit.com/r/<sub>` (or `r/<sub>`) | `reddit_channel` | that subreddit's threads, paginated |
|
|
2364
|
+
| `https://x.com/<user>/status/<id>` | `twitter_thread` | the tweet + the author's self-thread + its replies, paginated |
|
|
2365
|
+
| `https://x.com/<user>` (or `@<user>`) | `twitter_channel` | that account's tweets (pinned first), paginated |
|
|
2366
|
+
|
|
2367
|
+
A fifth mode, `reddit_user` (`https://reddit.com/user/<name>` or `u/<name>`), returns a redditor's posts and comments. Pass `mode` explicitly to override auto-detection, or `handle` + `network` instead of a URL.
|
|
2368
|
+
|
|
2369
|
+
### Payload
|
|
2370
|
+
|
|
2371
|
+
| Field | Default | Notes |
|
|
2372
|
+
| --- | --- | --- |
|
|
2373
|
+
| `source_url` | — | Reddit/X URL. Required unless you pass `handle` + `network`. Aliases: `url`, `thread_url`, `profile_url` |
|
|
2374
|
+
| `handle` + `network` | — | `{ "handle": "wallstreetbets", "network": "reddit" }`. Aliases for handle: `username`, `screenname`, `subreddit` |
|
|
2375
|
+
| `mode` | auto | Override the detected shape |
|
|
2376
|
+
| `max_records` | `100` | Cap on records (1–1000). The lead-gen apps auto-paginate to reach it and reserve credits for `ceil(max_records / 25)` pages — **this is your spend ceiling** |
|
|
2377
|
+
| `cursor` | — | Resume token from a previous run's `nextCursor` |
|
|
2378
|
+
| `prompt_filter` | — | Hand the lead-gen app a Gemini scoring prompt; adds `match_score` + `ai_notes` per item and costs slightly more per task upstream. We surface it and never act on it |
|
|
2379
|
+
| `query` | — | Restrict a channel pull to matching posts (Reddit search / X `from:<user> <query>`) |
|
|
2380
|
+
| `filter` / `sort` / `time_filter` | — | Reddit listing controls (`hot`, `new`, `top`, …) |
|
|
2381
|
+
| `search_type` | — | X search mode (`Top`, `Latest`, `Photos`, `Videos`) |
|
|
2382
|
+
| `include_profile` | `true` | One extra upstream job for the subreddit/account avatar, banner, bio, follower count |
|
|
2383
|
+
| `include_comments` | `true` | Thread modes only — set `false` to skip the replies leg (and its cost) |
|
|
2384
|
+
| `save_raw` | `true` | Persist the untouched upstream pages as `raw-pages.json` |
|
|
2385
|
+
|
|
2386
|
+
### Result
|
|
2387
|
+
|
|
2388
|
+
Poll `GET /api/v1/primitives/jobs/:jobId` until `status: "succeeded"`, then read:
|
|
2389
|
+
|
|
2390
|
+
- `items[]` — the normalized view. Each entry: `{ network, kind: "post" | "comment", id, title, text, created_at, permalink, link_url, author: { handle, name, avatar_url, banner_url, followers, profile_url, bio, verified }, stats: { … }, media: [{ type: "image"|"video"|"gif", url, thumbnail_url, width, height, duration_ms }] }`. X video media resolves to the **highest-bitrate MP4** variant, not the HLS manifest.
|
|
2391
|
+
- `profile` — the subreddit/account itself (avatar, banner, bio, subscriber/follower count).
|
|
2392
|
+
- `mediaUrls[]` — every media URL flattened, ready to drop into layers or feed to `videos/download`.
|
|
2393
|
+
- `nextCursor` — pass it back as `payload.cursor` to page further. `truncated: true` means there IS more.
|
|
2394
|
+
- `counts` — `{ items, posts, comments, media, pages, upstream_jobs, credits_charged }`.
|
|
2395
|
+
- `upstreamJobs[]` — one entry per lead-gen job we ran: `{ network, endpoint, job_id, status, tasks, credits_charged, view_url }`. **`view_url` opens a NocoDB spreadsheet of that pull — hand it to the human when they want to browse results visually.**
|
|
2396
|
+
- `recycled.json` (also `primary_file_url`) — the **complete** normalized payload. `items` in the job result is trimmed when it would blow the job-record size limit; `itemsTruncatedInline: true` tells you to read the artifact instead.
|
|
2397
|
+
- `raw-pages.json` — every untouched upstream page, so you can reach fields this primitive doesn't model.
|
|
2398
|
+
|
|
2399
|
+
- Billing: wallet, metered on the **OfficeX credits the lead-gen apps actually consumed** (`officex_social_recycle`), converted at `OFFICEX_CREDIT_USD`. A one-task thread costs a fraction of a 10-page timeline. Paid plans only — free plans get `402`, same as the download routes. If the *upstream* app runs out of OfficeX credits you get a `402` naming that app, which is an operator problem, not a customer one.
|
|
2400
|
+
- devcli wrapper: `vidfarm recycle <source>` (aliases: `recycle-social`, `tweet-to-video`, `reddit-to-video`). Flags: `--max-records N`, `--cursor`, `--query`, `--filter hot|new|top`, `--mode`, `--network`, `--no-comments`, `--no-profile`, `--out ./recycled.json` (writes the FULL normalized payload to disk), `--no-wait`. It prints the counts, the upstream NocoDB `view_url`s, and the resume cursor.
|
|
2401
|
+
- Legs: a recycle runs 1–3 upstream jobs (profile, feed, replies) **sequentially**, so a failure on the first never pays for the second. The optional profile leg degrades rather than sinking the pull.
|
|
2402
|
+
- Timeouts: upstream polling gives up after `SOCIAL_RECYCLE_POLL_TIMEOUT_MS` (default 5 min); the upstream job may still finish and can be browsed in that app.
|
|
2403
|
+
|
|
2404
|
+
### Turning a recycle into a video
|
|
2405
|
+
|
|
2406
|
+
1. Recycle the source with a small `max_records` (25–50 is usually plenty for one video).
|
|
2407
|
+
2. Read `items[]` yourself and pick the beat: the post's hook line, the two funniest comments, the stat everyone reacted to.
|
|
2408
|
+
3. Pull any `media[].url` you want as real footage through `videos/download` or straight into a layer; use `profile.avatar_url` for the "who said this" badge.
|
|
2409
|
+
4. Script and build as normal. **The recycled text is source material, not a script** — rewrite it to the hook/loop/payoff standard rather than pasting a comment thread on screen.
|
|
2410
|
+
|
|
2411
|
+
Example:
|
|
2412
|
+
|
|
2413
|
+
```bash
|
|
2414
|
+
curl -X POST "$VIDFARM_BASE/api/v1/primitives/social/recycle" \
|
|
2415
|
+
-H "vidfarm-api-key: $VIDFARM_API_KEY" \
|
|
2416
|
+
-H "content-type: application/json" \
|
|
2417
|
+
-d '{"tracer": "demo-recycle", "payload": {"source_url": "https://www.reddit.com/r/wallstreetbets/comments/p0esdp/slug/", "max_records": 50}}'
|
|
2418
|
+
```
|
|
2419
|
+
|
|
2420
|
+
```bash
|
|
2421
|
+
# An X account's recent posts, no replies, cheapest possible pull
|
|
2422
|
+
curl -X POST "$VIDFARM_BASE/api/v1/primitives/recycle-social" \
|
|
2423
|
+
-H "vidfarm-api-key: $VIDFARM_API_KEY" \
|
|
2424
|
+
-H "content-type: application/json" \
|
|
2425
|
+
-d '{"tracer": "demo-recycle-x", "payload": {"source_url": "https://x.com/elonmusk", "max_records": 40, "include_profile": true}}'
|
|
2426
|
+
```
|
|
2427
|
+
|
|
2327
2428
|
## Primitive: video_remove_captions
|
|
2328
2429
|
|
|
2329
2430
|
Remove burned-in captions/subtitles/on-screen text from any video URL (GhostCut-powered — the same pipeline auto-decompose uses for its caption-free mirror, exposed as a standalone reusable primitive). Result is a durable caption-free MP4 stored at a Vidfarm URL.
|
|
@@ -2678,7 +2779,7 @@ The mechanical trio — **generate on a chroma plate → key it out → trim to
|
|
|
2678
2779
|
- **Female TTS narration.** Default to a warm, friendly **female** voice and say which one you picked: local-first `vidfarm tts "<script>" --voice coral` (OpenAI — `nova` if the script wants more energy, `sage` for calmer), `--voice Kore` or `Leda` on Gemini, or `vidfarm voices` → `vidfarm tts --cloud --voice <voice_id>` on ElevenLabs. Tell the director they can swap it in one flag.
|
|
2679
2780
|
- **Clean and simple wins.** One idea on screen at a time. Two or three cutouts per beat, not eight. Generous white space, one accent color, one font. When in doubt, remove an element rather than add one.
|
|
2680
2781
|
|
|
2681
|
-
**Illustrations default to simplicity.** Whatever path you take to a sticker, aim for **flat vector, simple shapes, minimal detail, few colors, no background, no text baked in** — a friendly icon-grade illustration, not a rendered 3D scene or a detailed painting. Simple art keys cleanly, trims tight, scales without mush, animates readably at 9:16, and stays on-style across a whole cast. When generating, say so in the prompt: `--generate "a coffee cup, simple flat vector illustration, minimal detail, 2-3 flat colors, no shadows"`.
|
|
2782
|
+
**Illustrations default to simplicity — and to SOLID FILLS.** Whatever path you take to a sticker, aim for **flat vector, simple shapes, minimal detail, few colors, solid opaque fills, no background, no text baked in** — a friendly icon-grade illustration, not a rendered 3D scene or a detailed painting. Simple art keys cleanly, trims tight, scales without mush, animates readably at 9:16, and stays on-style across a whole cast. "Solid fills" is the load-bearing word: **outline-only art has its interior keyed away and comes back as a rim around a transparent hole** (see "Then make the ART key-safe too" below). When generating, say so in the prompt: `--generate "a coffee cup, simple flat vector illustration, minimal detail, 2-3 flat colors, solid filled shapes (not outline-only), no shadows"`.
|
|
2682
2783
|
|
|
2683
2784
|
**In cost-saving mode, don't generate illustrations at all — mask them out of images the director already has.** If `vidfarm cost-mode` is `minimize` (or the director says "without burning credits"), the default for adding an illustration is `vidfarm mask <their-image> --crop …` — lifting art out of an infographic, poster, deck slide, brand sheet, or screenshot for **$0 and zero AI calls**. Ask for source art before you ask for a generation budget; the guided loop is **"Mask from an image you already have"** below. **If no source art exists and the graphic must be custom, you still don't have to spend** — hand the director a prompt for a **free** image generator (meta.ai / free ChatGPT / a Hugging Face Space) and cut the returned sheet into stickers locally: **"Free manual image-gen"** below.
|
|
2684
2785
|
|
|
@@ -2723,6 +2824,20 @@ Out comes `./stickers/sticker-01-red-barn.png`, `sticker-02-tractor.png`, … ea
|
|
|
2723
2824
|
|
|
2724
2825
|
Override whenever you know better: `--key-color "#FF00FF"` or `--preset magenta` pins the plate (and turns the auto-pick off); `--no-auto-key` forces plain green. If a pack's palette collides with *every* standard plate — a rainbow icon set — split it across two sheets on two different plates rather than fighting `--tolerance`. And when a sticker is a *green* subject, never let the user generate it on green: the hand-off brief (`vidfarm handoff image`) already picks the plate for them and carries the matching `--key-color` into the follow-up command.
|
|
2725
2826
|
|
|
2827
|
+
**Then make the ART key-safe too — CLOSED, SOLIDLY FILLED shapes.** Picking the right plate is only half of surviving the key. The other half is the failure you actually see in the wild: you ask for "sticker icons on a green plate" and the model draws **outline art** — a colored stroke with the shape's *interior left as bare plate*. On the sheet it looks perfect. After the key, the interior is gone with the background, and every sticker composites as a **rim floating around a see-through hole** (an apple that's just an apple-shaped outline, a clock with no face). Same result from three cousins: a fill that's a *near-shade* of the plate (the keyer works on tolerance, not exact match), a **translucent/glassy/glowing** material that lets the plate through, and a **soft glow or drop shadow** that fades into the plate at the edges.
|
|
2828
|
+
|
|
2829
|
+
None of that is fixable after generation — you cannot key back pixels that were never drawn. So it belongs in the **prompt**, every time:
|
|
2830
|
+
|
|
2831
|
+
> Every object must be a CLOSED, SOLIDLY FILLED shape — outlines and strokes must enclose an opaque fill of a different color. No outline-only, hollow, or line-art objects; never leave a shape's interior as bare background. No part of any object — fill, outline, highlight, gradient, shading or detail — may be `<PLATE HEX>` or any near-shade, tint or tone of it. No transparent, translucent, glassy, glowing or ghosted materials; every pixel of every object is fully opaque. No soft glows, blurs or drop shadows fading into the background. Keep the whole palette in strong contrast to `<PLATE HEX>`. The background must be visible ONLY around the outside of the objects, never showing through inside them.
|
|
2832
|
+
|
|
2833
|
+
`cutout --generate`, `sticker-pack --generate`, `vidfarm handoff image`, and the `create-overlay` REST primitive all append that clause automatically with the chosen plate hex substituted in — **you only have to write it yourself when you're prompting a generator directly** (a free web tool by hand, or your own `POST /api/v1/primitives/images/generate` call). Do write it. It costs one paragraph and it is the difference between a usable pack and a re-generation.
|
|
2834
|
+
|
|
2835
|
+
**And it's checked after the key.** `sticker-pack` and `cutout` measure, per item, the transparent area **fully enclosed by that item's own art** and report it as `hole_pct` (plus `holes`, and `hollow: true` at ≥20%) in `--json`, in `stickers.json`, and as a `⚠ N% hollow` flag on the console line. A ring, donut, picture frame or letter "O" reads the same way, so it **warns, never blocks** — the judgement is yours. When items you expected to be solid come back flagged:
|
|
2836
|
+
|
|
2837
|
+
- **Re-generate the sheet** with the fill clause above spelled out. This is the fix ~90% of the time.
|
|
2838
|
+
- If the fill was merely *close* to the plate rather than absent, a lower `--tolerance` can rescue the sheet you already have. Nothing rescues a genuinely empty interior.
|
|
2839
|
+
- Last resort for one stubborn item: `vidfarm mask ./sheet.png --crop x,y,w,h` — ONNX matting doesn't care what color the fill is, so it lifts art the chroma key can't.
|
|
2840
|
+
|
|
2726
2841
|
**Generation is the failure point, not the cutting.** The sheet prompt is auto-appended with the important instruction — *every item fully separated by clear plate-colored background, nothing touching or overlapping, wide margins, no text, no shadows, one consistent style* — because **touching items segment as one sticker**. If a pack comes back merged, re-run the generation asking for more spacing before you fight the `--gap` knob.
|
|
2727
2842
|
|
|
2728
2843
|
### Stickers are not necessarily small — and they usually move
|
|
@@ -2839,15 +2954,15 @@ Everything here is **local and free** — crop, matte/key, and trim are all `ffm
|
|
|
2839
2954
|
|
|
2840
2955
|
1. **List the cast.** Name every illustration the explainer needs, in the house style (flat vector, 2–3 flat colors, no baked-in text).
|
|
2841
2956
|
2. **Hand the director this prompt**, filled in:
|
|
2842
|
-
> A flat vector illustration sheet on a solid pure green background (#00FF00), no gradient, no shadow, no text, no labels. Arranged in a 3×2 grid with generous even spacing, each object fully separated and not touching any other object or the image edge: (1) `<object one>`, (2) `<object two>`, (3) `<object three>`, … Simple flat shapes, 2–3 flat colors, minimal detail, consistent style and line weight across all objects, front-facing, centered in its own cell. Square image, high resolution.
|
|
2957
|
+
> A flat vector illustration sheet on a solid pure green background (#00FF00), no gradient, no shadow, no text, no labels. Arranged in a 3×2 grid with generous even spacing, each object fully separated and not touching any other object or the image edge: (1) `<object one>`, (2) `<object two>`, (3) `<object three>`, … Simple flat shapes, 2–3 flat colors, minimal detail, consistent style and line weight across all objects, front-facing, centered in its own cell. **Every object is a closed, solidly filled shape — outlines must enclose an opaque fill of a different color; no outline-only or hollow objects, and no object's interior left as bare green. Nothing on any object may be green or any near-shade of green; no transparent, translucent, glassy or glowing materials; no soft glows or drop shadows fading into the background.** Square image, high resolution.
|
|
2843
2958
|
|
|
2844
|
-
**No text in the image, ever** — rendered text never keys or scales cleanly; add copy as a caption or HTML layer instead.
|
|
2959
|
+
**No text in the image, ever** — rendered text never keys or scales cleanly; add copy as a caption or HTML layer instead. **And don't drop the bolded fill sentence** — the green gets deleted, so anything green *on* the art gets deleted with it; hollow outline art is the single most common way a hand-generated sheet comes back broken. (`vidfarm handoff image --theme … --items …` mints this whole brief with the plate and the fill clause already filled in — prefer it over typing the prompt yourself.)
|
|
2845
2960
|
3. **Bring the sheet in:** `vidfarm put-file ./sheet.png` (or drag into **My Files** in the web app).
|
|
2846
2961
|
4. **Split it into stickers — one command, all free:**
|
|
2847
2962
|
```
|
|
2848
2963
|
vidfarm sticker-pack ./sheet.png --items "<object one>,<object two>,…" --out-dir ./stickers
|
|
2849
2964
|
```
|
|
2850
|
-
It keys the flat green, finds each object in the alpha channel, and writes one trimmed transparent sticker per object (named from `--items`) plus `stickers.json`. Run it with `--dry-run` first to check the boxes. Two objects merged into one? The generator drew them too close — lower `--gap`, or grab that pair by hand:
|
|
2965
|
+
It keys the flat green, finds each object in the alpha channel, and writes one trimmed transparent sticker per object (named from `--items`) plus `stickers.json`. Run it with `--dry-run` first to check the boxes. Any item flagged **`⚠ N% hollow`** came back as an outline around a transparent hole — unless it's genuinely a ring/frame, re-ask the director for that sheet with the fill sentence, or lift that one item with `vidfarm mask ./sheet.png --crop x,y,w,h` (ONNX matting doesn't care what the fill color is). Two objects merged into one? The generator drew them too close — lower `--gap`, or grab that pair by hand:
|
|
2851
2966
|
```
|
|
2852
2967
|
vidfarm mask ./sheet.png --crop 4%,4%,29%,45% --flat "#00FF00" --out prop-a.png
|
|
2853
2968
|
```
|
package/SKILL.md
CHANGED
|
@@ -41,7 +41,7 @@ The last two are production *methods*, not just budgets. **rich-ai**: generate t
|
|
|
41
41
|
|
|
42
42
|
**Even in `minimize`, you can still get custom images — for free, manually.** When stock and masking existing art won't cover a bespoke graphic, don't say "not possible" and don't quietly spend: ask the user once whether to **default to free manual image generation**, then write the prompt and have them run it in <https://meta.ai>, free-tier ChatGPT, or a free Hugging Face image Space, and hand the PNG back (`vidfarm put-file`, or drag into My Files). Ask for **one image containing every graphic you need**, gridded on a **flat chroma plate** with no text (`#00FF00` green by default — but pick a different plate when the art itself is green, or the key will punch holes through it) — one round trip instead of many, which is the token-efficient move. Then split it locally at $0 in one command: `vidfarm sticker-pack ./sheet.png --items "a,b,c" --out-dir ./stickers` keys the green out, finds each item in the sheet automatically, and writes a snug transparent sticker per item. Prompt template + full loop in the director skill.
|
|
43
43
|
|
|
44
|
-
**"Make me a sticker pack" = one greenscreen sheet, then masked apart.** A pack is a *set* that has to share one art style, so never generate the items one by one — generate a single image holding all of them on a flat `#00FF00` plate, then split it: `vidfarm sticker-pack --generate "<theme>" --items "a,b,c,d"` (one billed image job for the whole set, then free local keying + automatic alpha segmentation + per-item trim + a `stickers.json` manifest). **The plate must be a color the art doesn't use** — a green pack (leaves, frogs, plants, money) on a green plate keys holes through the art. The commands pick the plate off the subject when generating (green → magenta → blue → black → white, and they tell you when they move) and **detect the plate from an existing sheet's corners**, so a red or purple sheet from a web tool just works; pin it with `--key-color`/`--preset`, or `--no-auto-key` for plain green. Stickers are **not necessarily small** — a full-frame landscape or backdrop is as valid an item as an icon — and they're normally **animated on the canvas** (`vidfarm place` + `vidfarm keyframes` presets: pop-in, float, shake, grow, slide-in, drift). A sticker whose own art moves is a **transparent WebM** (`vidfarm remove-greenscreen <video>`), and for GIF-only surfaces both paths can emit **transparent GIFs** (`sticker-pack --output-format gif`, `remove-greenscreen --gif`, 1-bit alpha). Full recipe in the director skill.
|
|
44
|
+
**"Make me a sticker pack" = one greenscreen sheet, then masked apart.** A pack is a *set* that has to share one art style, so never generate the items one by one — generate a single image holding all of them on a flat `#00FF00` plate, then split it: `vidfarm sticker-pack --generate "<theme>" --items "a,b,c,d"` (one billed image job for the whole set, then free local keying + automatic alpha segmentation + per-item trim + a `stickers.json` manifest). **The plate must be a color the art doesn't use** — a green pack (leaves, frogs, plants, money) on a green plate keys holes through the art. The commands pick the plate off the subject when generating (green → magenta → blue → black → white, and they tell you when they move) and **detect the plate from an existing sheet's corners**, so a red or purple sheet from a web tool just works; pin it with `--key-color`/`--preset`, or `--no-auto-key` for plain green. **And the art itself must be closed and solidly filled** — outline-only/hollow art (or a near-plate fill, or anything translucent/glowing) has its interior keyed away and composites as a rim around a see-through hole. The generation prompts say so for you; write it in by hand when you prompt a generator directly, and check the `⚠ N% hollow` / `hole_pct` flag each command reports after keying. Stickers are **not necessarily small** — a full-frame landscape or backdrop is as valid an item as an icon — and they're normally **animated on the canvas** (`vidfarm place` + `vidfarm keyframes` presets: pop-in, float, shake, grow, slide-in, drift). A sticker whose own art moves is a **transparent WebM** (`vidfarm remove-greenscreen <video>`), and for GIF-only surfaces both paths can emit **transparent GIFs** (`sticker-pack --output-format gif`, `remove-greenscreen --gif`, 1-bit alpha). Full recipe in the director skill.
|
|
45
45
|
|
|
46
46
|
## Ask the second question too — interactive or autonomous?
|
|
47
47
|
|
|
@@ -101,6 +101,7 @@ For composition *authoring* craft (motion, keyframes, scene design), Vidfarm shi
|
|
|
101
101
|
3. "Change / re-theme this video" → `references/editor-workflows.md`
|
|
102
102
|
4. "Find footage / use our assets" → `references/assets-and-sourcing.md`
|
|
103
103
|
4b. **"Download this video/audio from <a website URL>"** → Vidfarm fetches it for you on a **paid plan**: `POST /api/v1/primitives/videos/download` (or `/audio/download`); devcli `vidfarm download-video <url>` / `vidfarm download-audio <url>`. Works on YouTube, TikTok, Instagram, X, and other supported posts; returns a durable Vidfarm file (photo/carousel posts → an ordered slideshow). **Free plan gets a 402 — don't call it. Tell the user (or, with browser automation, do it yourself) to open the URL in Chrome and download it from the page, then `vidfarm put-file ./the-file.mp4` to bring it in for $0.** Never answer "I can't download that." Details: `references/assets-and-sourcing.md`.
|
|
104
|
+
4b-ii. **"Tweet to TikTok" / "Reddit to TikTok" / "make a video out of this thread / subreddit / account"** → `vidfarm recycle <source>` (devcli), or `POST /api/v1/primitives/social/recycle` with `{ tracer, payload: { source_url, max_records } }`. It **decomposes** a Reddit thread (post + comments), a subreddit (its threads), an X thread (tweet + replies), or an X profile (their posts) into raw JSON — text, comment tree, media URLs, author avatar, engagement stats — and hands it back **unranked and unsummarized** so you pick the hook, the punchline comment, the stat. Auto-paginates via `nextCursor`; `max_records` is the spend ceiling. Brokers the reddit-lead-gen / x-lead-gen OfficeX apps and waits out their async job for you. **Paid plan.** Details: `references/assets-and-sourcing.md`.
|
|
104
105
|
4c. **"Create an avatar"** (spokesperson / presenter / host / UGC creator / talking head) → always a **talking-head VIDEO with spoken audio**, generated on an exact-key-color **greenscreen** plate and keyed off it in the same job → a **transparent presenter** you layer over any background. `vidfarm avatar "<who they are>" --say "<their line>" [--ref headshot.png]` / `POST /api/v1/primitives/videos/create-avatar`. Details: `references/primitives.md` → "Primitive: talking_avatar".
|
|
105
106
|
5. "Script / batch / render loop" → `references/automation-and-local-dev.md`
|
|
106
107
|
6. "I need TTS / music / captions / background removal" → `references/primitives.md`
|