@officexapp/vidfarm-devcli 0.21.54 → 0.21.55
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 +3 -0
- package/.agents/skills/vidfarm/harnesses/README.md +26 -0
- package/.agents/skills/vidfarm/recipes/bulk-scripting-with-a-harness.md +2 -1
- package/.agents/skills/vidfarm/references/automation-and-local-dev.md +2 -2
- package/SKILL.director.md +7 -3
- package/SKILL.md +3 -0
- package/clipper.md +4 -2
- package/dist/src/cli.js +32 -8
- package/dist/src/devcli/harness.js +60 -15
- package/dist/src/devcli/skill-docs.js +2 -1
- package/experimental/animated-sticker-story.md +2252 -0
- package/experimental/google-news-to-video.md +9 -0
- package/experimental/unique-product-explainers.md +8 -0
- package/marketplace.md +5 -0
- package/package.json +1 -1
|
@@ -439,6 +439,8 @@ Vidfarm keeps a small shelf of **experimental prompts**: complete, standalone me
|
|
|
439
439
|
|
|
440
440
|
Why they exist: the prompts you find on the `/discover` pages are tuned to **one template's format**. These are deliberately **generalized** — the method, not the template — so they transfer to whatever you are building. The live index is `https://vidfarm.cc/experimental` (always current); today it holds:
|
|
441
441
|
|
|
442
|
+
**Two ways to reach any of them.** Fetch the URL, or read it **by name, offline** — every one of these ships inside the devcli package: `vidfarm harness list` prints this same shelf under *Format harnesses*, `vidfarm harness show <name>` prints one (`--dna <strand>` for a single strand), and `vidfarm qa ./work --harness <name>` grades a build against it. The name is the URL slug, and underscores resolve too — `meme_recaption` and `meme-recaption` are the same harness in both places. Prefer the CLI when you already have it: no fetch, no 402, and it stacks with a base (`--harness google-news-to-video --harness short-form`).
|
|
443
|
+
|
|
442
444
|
| Prompt | What it does |
|
|
443
445
|
|---|---|
|
|
444
446
|
| `https://vidfarm.cc/experimental/unique-product-explainers.md` | N customer URLs → N product-introduction videos that do not look like each other. Differentiation as an input, frame-level review, measured verification |
|
|
@@ -447,6 +449,7 @@ Why they exist: the prompts you find on the `/discover` pages are tuned to **one
|
|
|
447
449
|
| `https://vidfarm.cc/experimental/ugc-reaction-greenscreen.md` | Sell an app with three streams cut against each other: `ugc-reaction` raws, a Display Greenscreen device whose screen carries the customer's real demo, and the demo itself. One actor across every beat via `actor_<uuid>`, a per-frame tracked screen insert, captions inside the platform-chrome-safe core, and two exports from one render (voiceover-only to publish, voiceover+music to review) |
|
|
448
450
|
| `https://vidfarm.cc/experimental/sticker-slideshow-tips.md` | A tips **carousel** — the deliverable is N still slides, and the 3.0s-per-slide MP4 is only the playable preview. Die-cut cutouts on a paper page or a photo background, a literal "Tips for…" cover, the specificity ladder, one slide shilled from the middle and written so it survives deleting the brand name, four background modes, and a measured WCAG contrast gate on the exported PNGs |
|
|
449
451
|
| `https://vidfarm.cc/experimental/wall-text-pov-ugc.md` | One unbroken ambient take + one static block of unplated type. No cuts, no voiceover, no subtitles, nothing animated. The retention engine is arithmetic — `duration = words / 8`, so one play lands the viewer at the **halfway mark**, committed and one pass from done — floored at 8s so a trending sound gets a real phrase of a track. The four speaker frames, MIRROR vs TURN, a density pass that treats padding as the fatal failure, casting the scene dark so the type needs no plate (measured), ping-ponging the plate for a seamless loop, and three gates. Runs at $0 |
|
|
452
|
+
| `https://vidfarm.cc/experimental/animated-sticker-story.md` | A narrated **paper puppet theater** — one full-bleed parchment stage that never cuts, a cast of die-cut stickers, and every element moved by ONE paused GSAP timeline (MotionPathPlugin for walks; paths in absolute canvas coordinates, never `align:"self"`). The three-node rig, the seven moves (ENTER / WALK / CROWD / BEAT / STAMP / DRAW / CAMERA), buying SHEETS rather than stickers so one art class survives, generating art without shadows and adding one CSS drop-shadow, kinetic captions that animate **colour only** on whisper word timings, a two-pass build that MEASURES where the drawing is quietest before placing any type, a feathered paper wash that is not a plate, and the offer named once as a wordmark on the last beat. Desktop-only. ~$0.25 in `hybrid`, $0 in `minimize` |
|
|
450
453
|
|
|
451
454
|
Fetch one as plain markdown and follow it end to end; do not skim it into a summary.
|
|
452
455
|
|
|
@@ -111,3 +111,29 @@ The `.harness/` directory a `vidfarm pull` writes is a different thing: machine-
|
|
|
111
111
|
| `explainer` | Faceless educational video: one claim, invented visuals |
|
|
112
112
|
| `product-demo` | Real product doing a real thing — the highest slop-risk format in the catalog |
|
|
113
113
|
| `product-explainer` | Introducing a product a stranger has never heard of, with no usable screen footage. The plain-English line, the simple sticker-led open, per-client differentiation |
|
|
114
|
+
|
|
115
|
+
## Format harnesses — the second shelf
|
|
116
|
+
|
|
117
|
+
`vidfarm harness list` prints the bases above **and** the format harnesses: complete contracts for
|
|
118
|
+
ONE format, published at `https://vidfarm.cc/experimental` and shipped inside the CLI package under
|
|
119
|
+
the same name as their URL slug. A base is a starting point you edit; a format harness is a method
|
|
120
|
+
you follow. Read one **before** you build that format, and stack it on a base.
|
|
121
|
+
|
|
122
|
+
| Name | For |
|
|
123
|
+
|---|---|
|
|
124
|
+
| `meme-recaption` | One borrowed meme clip, one new caption aimed at the offer's problem space |
|
|
125
|
+
| `wall-text-pov-ugc` | One unbroken ambient take + one static block of unplated type. `duration = words / 8` |
|
|
126
|
+
| `ugc-reaction-greenscreen` | Reaction cutaways + a keyed device carrying the customer's real app demo |
|
|
127
|
+
| `sticker-slideshow-tips` | A tips carousel — N still slides at 3.0s; the slides are the deliverable |
|
|
128
|
+
| `animated-sticker-story` | A narrated paper puppet theater on one parchment stage, one GSAP timeline |
|
|
129
|
+
| `google-news-to-video` | Timely newsjack — news-search finds the STORY, video-search the VISUALS |
|
|
130
|
+
| `unique-product-explainers` | N customer URLs → N videos that do not converge. Differentiation as an input |
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
vidfarm harness list # both shelves
|
|
134
|
+
vidfarm harness show wall-text-pov-ugc # the whole contract, no fetch
|
|
135
|
+
vidfarm qa ./work --harness wall-text-pov-ugc --harness short-form # they STACK
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Underscores resolve too (`meme_recaption` = `meme-recaption`), on the CLI and at the URL. The web
|
|
139
|
+
index is the source of truth for what exists; `vidfarm harness list` is the same shelf, offline.
|
|
@@ -26,7 +26,8 @@ Two ways in, depending on where the format came from:
|
|
|
26
26
|
|
|
27
27
|
```bash
|
|
28
28
|
# (a) From a bundled base — when the format is one you're defining
|
|
29
|
-
vidfarm harness list # short-form | hooks | ugc-testimonial | explainer | product-demo | product-explainer
|
|
29
|
+
vidfarm harness list # bases: short-form | hooks | ugc-testimonial | explainer | product-demo | product-explainer
|
|
30
|
+
# + format harnesses: meme-recaption | wall-text-pov-ugc | … (the /experimental shelf, offline)
|
|
30
31
|
vidfarm harness init hooks --out ./work/HARNESS.md
|
|
31
32
|
|
|
32
33
|
# (b) From the template you're batching — when the format is one you're REPLICATING
|
|
@@ -62,7 +62,7 @@ A director who says "make me a video about X" usually wants the first. A directo
|
|
|
62
62
|
| "give me the harness for this template_id" | `vidfarm harness derive <templateId\|forkId>` — the **decomposition**, as a harness |
|
|
63
63
|
|
|
64
64
|
```bash
|
|
65
|
-
vidfarm harness list # the
|
|
65
|
+
vidfarm harness list # bases to edit + the format harnesses (vidfarm.cc/experimental, offline)
|
|
66
66
|
vidfarm harness init short-form --out ./work/HARNESS.md # copy, then EDIT it
|
|
67
67
|
vidfarm harness derive <forkId> --out ./work/HARNESS.md # a decomposed template → a harness
|
|
68
68
|
vidfarm harness show ./work/HARNESS.md --dna visual # ONE strand, not the whole doc
|
|
@@ -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
|
-
|
|
87
|
+
`vidfarm harness list` prints **two shelves**. The second one is the format harnesses — the `https://vidfarm.cc/experimental` shelf, shipped in the package so `vidfarm harness show meme-recaption` works with no fetch. Those are complete contracts for ONE format: read one before you build that format, and stack it on a base (`--harness wall-text-pov-ugc --harness short-form`). The first shelf is the bundled bases (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
|
|
package/SKILL.director.md
CHANGED
|
@@ -439,6 +439,8 @@ Vidfarm keeps a small shelf of **experimental prompts**: complete, standalone me
|
|
|
439
439
|
|
|
440
440
|
Why they exist: the prompts you find on the `/discover` pages are tuned to **one template's format**. These are deliberately **generalized** — the method, not the template — so they transfer to whatever you are building. The live index is `https://vidfarm.cc/experimental` (always current); today it holds:
|
|
441
441
|
|
|
442
|
+
**Two ways to reach any of them.** Fetch the URL, or read it **by name, offline** — every one of these ships inside the devcli package: `vidfarm harness list` prints this same shelf under *Format harnesses*, `vidfarm harness show <name>` prints one (`--dna <strand>` for a single strand), and `vidfarm qa ./work --harness <name>` grades a build against it. The name is the URL slug, and underscores resolve too — `meme_recaption` and `meme-recaption` are the same harness in both places. Prefer the CLI when you already have it: no fetch, no 402, and it stacks with a base (`--harness google-news-to-video --harness short-form`).
|
|
443
|
+
|
|
442
444
|
| Prompt | What it does |
|
|
443
445
|
|---|---|
|
|
444
446
|
| `https://vidfarm.cc/experimental/unique-product-explainers.md` | N customer URLs → N product-introduction videos that do not look like each other. Differentiation as an input, frame-level review, measured verification |
|
|
@@ -447,6 +449,7 @@ Why they exist: the prompts you find on the `/discover` pages are tuned to **one
|
|
|
447
449
|
| `https://vidfarm.cc/experimental/ugc-reaction-greenscreen.md` | Sell an app with three streams cut against each other: `ugc-reaction` raws, a Display Greenscreen device whose screen carries the customer's real demo, and the demo itself. One actor across every beat via `actor_<uuid>`, a per-frame tracked screen insert, captions inside the platform-chrome-safe core, and two exports from one render (voiceover-only to publish, voiceover+music to review) |
|
|
448
450
|
| `https://vidfarm.cc/experimental/sticker-slideshow-tips.md` | A tips **carousel** — the deliverable is N still slides, and the 3.0s-per-slide MP4 is only the playable preview. Die-cut cutouts on a paper page or a photo background, a literal "Tips for…" cover, the specificity ladder, one slide shilled from the middle and written so it survives deleting the brand name, four background modes, and a measured WCAG contrast gate on the exported PNGs |
|
|
449
451
|
| `https://vidfarm.cc/experimental/wall-text-pov-ugc.md` | One unbroken ambient take + one static block of unplated type. No cuts, no voiceover, no subtitles, nothing animated. The retention engine is arithmetic — `duration = words / 8`, so one play lands the viewer at the **halfway mark**, committed and one pass from done — floored at 8s so a trending sound gets a real phrase of a track. The four speaker frames, MIRROR vs TURN, a density pass that treats padding as the fatal failure, casting the scene dark so the type needs no plate (measured), ping-ponging the plate for a seamless loop, and three gates. Runs at $0 |
|
|
452
|
+
| `https://vidfarm.cc/experimental/animated-sticker-story.md` | A narrated **paper puppet theater** — one full-bleed parchment stage that never cuts, a cast of die-cut stickers, and every element moved by ONE paused GSAP timeline (MotionPathPlugin for walks; paths in absolute canvas coordinates, never `align:"self"`). The three-node rig, the seven moves (ENTER / WALK / CROWD / BEAT / STAMP / DRAW / CAMERA), buying SHEETS rather than stickers so one art class survives, generating art without shadows and adding one CSS drop-shadow, kinetic captions that animate **colour only** on whisper word timings, a two-pass build that MEASURES where the drawing is quietest before placing any type, a feathered paper wash that is not a plate, and the offer named once as a wordmark on the last beat. Desktop-only. ~$0.25 in `hybrid`, $0 in `minimize` |
|
|
450
453
|
|
|
451
454
|
Fetch one as plain markdown and follow it end to end; do not skim it into a summary.
|
|
452
455
|
|
|
@@ -2907,7 +2910,7 @@ A director who says "make me a video about X" usually wants the first. A directo
|
|
|
2907
2910
|
| "give me the harness for this template_id" | `vidfarm harness derive <templateId\|forkId>` — the **decomposition**, as a harness |
|
|
2908
2911
|
|
|
2909
2912
|
```bash
|
|
2910
|
-
vidfarm harness list # the
|
|
2913
|
+
vidfarm harness list # bases to edit + the format harnesses (vidfarm.cc/experimental, offline)
|
|
2911
2914
|
vidfarm harness init short-form --out ./work/HARNESS.md # copy, then EDIT it
|
|
2912
2915
|
vidfarm harness derive <forkId> --out ./work/HARNESS.md # a decomposed template → a harness
|
|
2913
2916
|
vidfarm harness show ./work/HARNESS.md --dna visual # ONE strand, not the whole doc
|
|
@@ -2929,7 +2932,7 @@ vidfarm qa ./work --harness hooks --harness ./brand/HOUSE.md # built-in + your o
|
|
|
2929
2932
|
|
|
2930
2933
|
> 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.
|
|
2931
2934
|
|
|
2932
|
-
|
|
2935
|
+
`vidfarm harness list` prints **two shelves**. The second one is the format harnesses — the `https://vidfarm.cc/experimental` shelf, shipped in the package so `vidfarm harness show meme-recaption` works with no fetch. Those are complete contracts for ONE format: read one before you build that format, and stack it on a base (`--harness wall-text-pov-ugc --harness short-form`). The first shelf is the bundled bases (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.
|
|
2933
2936
|
|
|
2934
2937
|
**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.
|
|
2935
2938
|
|
|
@@ -4588,7 +4591,8 @@ Two ways in, depending on where the format came from:
|
|
|
4588
4591
|
|
|
4589
4592
|
```bash
|
|
4590
4593
|
# (a) From a bundled base — when the format is one you're defining
|
|
4591
|
-
vidfarm harness list # short-form | hooks | ugc-testimonial | explainer | product-demo | product-explainer
|
|
4594
|
+
vidfarm harness list # bases: short-form | hooks | ugc-testimonial | explainer | product-demo | product-explainer
|
|
4595
|
+
# + format harnesses: meme-recaption | wall-text-pov-ugc | … (the /experimental shelf, offline)
|
|
4592
4596
|
vidfarm harness init hooks --out ./work/HARNESS.md
|
|
4593
4597
|
|
|
4594
4598
|
# (b) From the template you're batching — when the format is one you're REPLICATING
|
package/SKILL.md
CHANGED
|
@@ -98,6 +98,8 @@ vidfarm publish <forkId> # push edits back to th
|
|
|
98
98
|
| "A UGC ad for my app" / "someone reacting, then the app" / a client's app demo you have to make watchable | three streams cut against each other: `ugc-reaction` raws (ONE actor, via `actor_<uuid>`), a Display Greenscreen device carrying their real demo on its screen, and the demo. Ships a voiceover-only cut to publish + a voiceover+music cut to review | `vidfarm.cc/experimental/ugc-reaction-greenscreen.md` |
|
|
99
99
|
| "A tips slideshow / carousel" / "5 tips for X" / a listicle post | N still slides at exactly 3.0s, die-cut cutouts on a page or a photo, a literal "Tips for…" cover, ONE slide shilled from the middle. **The slides are the deliverable; the MP4 is the preview.** $0–$0.15 | `vidfarm.cc/experimental/sticker-slideshow-tips.md` |
|
|
100
100
|
| "A confession / truth bomb over a POV or ambient scene" / "just text on a video" / a text-story post | ONE unbroken take + ONE static block of unplated type. Nothing animates, nothing is cut. `duration = words / 8` (min 8s) so one play reaches the HALFWAY mark and they loop to finish. Cast the scene DARK so the type needs no plate. $0 | `vidfarm.cc/experimental/wall-text-pov-ugc.md` |
|
|
101
|
+
| "An animated explainer / a little story that animates" / "like those Vox map animations" / "cutout paper animation" | ONE full-bleed parchment stage, no cuts, a cast of die-cut paper stickers moved by ONE paused GSAP timeline. Narrated, subtitles stay small and kinetic in colour only, the offer named once as a wordmark on the LAST beat. Buy SHEETS, not stickers. Desktop-only (the web editor strips scripts). ~$0.25 hybrid, $0 minimize | `vidfarm.cc/experimental/animated-sticker-story.md` |
|
|
102
|
+
| "Make N videos for N customers / clients" / a batch that must not read as N runs of one template | differentiation is an INPUT, not a hope: assign each variant its own frame before you build any of them, then review frame by frame. $0 | `vidfarm.cc/experimental/unique-product-explainers.md` |
|
|
101
103
|
| "Download this video from `<url>`" | `vidfarm download-video <url>` (paid). Free plan gets a 402 — `vidfarm browse page "<url>"` and save it from their Chrome yourself, else have them download it, then `vidfarm put-file`. Never answer "I can't." | `references/browser-harness.md` |
|
|
102
104
|
| "Turn this thread / subreddit / profile into a video" | `vidfarm recycle <source>` — returns the raw decomposition, unranked; you pick the hook (paid) | `references/assets-and-sourcing.md` |
|
|
103
105
|
| "Create an avatar / spokesperson / talking head" | `vidfarm avatar "<who>" --say "<line>"` — a greenscreen talking-head video, keyed in the same job | `references/primitives.md` |
|
|
@@ -195,6 +197,7 @@ Otherwise fetch `https://vidfarm.cc/skill-pack/vidfarm/files/<path>`. Load one f
|
|
|
195
197
|
| `references/rest-api.md` | direct HTTP integration only |
|
|
196
198
|
| `recipes/*.md` | `find-and-fork-template` · `retheme-template` · `local-edit-render-approve` · `onboard-a-new-director` · `bulk-scripting-with-a-harness` · `cutout-graphics-for-explainers` |
|
|
197
199
|
| `harnesses/README.md` | anything harness-shaped — start here. Bases: `short-form` · `hooks` · `ugc-testimonial` · `explainer` · `product-demo` · `product-explainer` |
|
|
200
|
+
| `vidfarm harness list` | both shelves: the bases above, **plus every format harness from `vidfarm.cc/experimental`** — `meme-recaption` · `wall-text-pov-ugc` · `ugc-reaction-greenscreen` · `sticker-slideshow-tips` · `animated-sticker-story` · `google-news-to-video` · `unique-product-explainers`. They ship in the package, so `vidfarm harness show <name>` reads one in full with no fetch, and `vidfarm qa ./work --harness <name>` grades against it. The name is the URL slug |
|
|
198
201
|
|
|
199
202
|
Also served at `vidfarm.cc`: `/experiments.md` (ad testing), `/marketplace.md` (the marketplace manual — routes you to one of the two side harnesses below), `/marketplace-buyer.md` (**buyer side**: commission videos from the crowd), `/agentic-clipper.md` (**worker side**: "Agentic Clipper" mode — one orchestrator on a long-horizon earning mission, one subagent per task), `/update.md` (upgrade runbook), `/experimental` (format harnesses under live testing — the index a clipper routes tasks against), `/skill/vidfarm-platform` (architecture), `/skill/hyperframes` (composition-authoring craft — route broad "make me a video" asks here first).
|
|
200
203
|
|
package/clipper.md
CHANGED
|
@@ -279,8 +279,10 @@ What matters for a clipper loop specifically:
|
|
|
279
279
|
built like a meme recaption gets rejected, and so does the reverse. Read the live index at
|
|
280
280
|
<https://vidfarm.cc/experimental> and pick — a product/feature introduction routes to
|
|
281
281
|
`unique-product-explainers.md`, a recaption or reaction routes to `meme-recaption.md`, a timely
|
|
282
|
-
event routes to `google-news-to-video.md`.
|
|
283
|
-
|
|
282
|
+
event routes to `google-news-to-video.md`. Each of those also ships inside the CLI under the same
|
|
283
|
+
name, so `vidfarm harness show meme-recaption` reads the whole contract with no fetch, and
|
|
284
|
+
`vidfarm qa ./work --harness meme-recaption` grades the build against it. Nothing fits? Fall back to
|
|
285
|
+
a CLI base (`vidfarm harness list`) — and if no harness fits at all, **freestyle it against the best practices
|
|
284
286
|
in <https://vidfarm.cc/skill.md>.** That is a normal outcome, not a failure: harnesses reproduce a
|
|
285
287
|
*known* format, and a task outside every known format is still one you can deliver well. Never force
|
|
286
288
|
a task into the wrong harness, and never decline one just because no harness matched.
|
package/dist/src/cli.js
CHANGED
|
@@ -925,9 +925,18 @@ Local media engines & toolchain (all local, free, no account — no cloud key ne
|
|
|
925
925
|
"create me a harness" / "update the harness for
|
|
926
926
|
this format" / "give me the harness for this
|
|
927
927
|
template_id" all land here
|
|
928
|
-
harness list [--json]
|
|
929
|
-
hooks, ugc-testimonial,
|
|
930
|
-
product-demo,
|
|
928
|
+
harness list [--json] Two shelves. BASES to copy and edit:
|
|
929
|
+
short-form, hooks, ugc-testimonial,
|
|
930
|
+
explainer, product-demo,
|
|
931
|
+
product-explainer. FORMAT harnesses —
|
|
932
|
+
complete contracts, read by name, same
|
|
933
|
+
shelf as vidfarm.cc/experimental:
|
|
934
|
+
meme-recaption, wall-text-pov-ugc,
|
|
935
|
+
ugc-reaction-greenscreen,
|
|
936
|
+
sticker-slideshow-tips,
|
|
937
|
+
animated-sticker-story,
|
|
938
|
+
google-news-to-video,
|
|
939
|
+
unique-product-explainers
|
|
931
940
|
harness show <name|path> Print one [--dna <strand>] to print just
|
|
932
941
|
one strand (viral_dna, visual_dna, …)
|
|
933
942
|
harness init <name> [--out <p>] Copy one next to your work, then EDIT it
|
|
@@ -12344,13 +12353,28 @@ async function runHarnessCommand(argv) {
|
|
|
12344
12353
|
});
|
|
12345
12354
|
const json = Boolean(parsed.values.json);
|
|
12346
12355
|
if (!sub || sub === "list") {
|
|
12347
|
-
const
|
|
12348
|
-
if (json)
|
|
12349
|
-
return printJson({
|
|
12350
|
-
|
|
12351
|
-
|
|
12356
|
+
const all = listBuiltinHarnesses();
|
|
12357
|
+
if (json) {
|
|
12358
|
+
return printJson({
|
|
12359
|
+
harnesses: all.map(({ name, path: file, video_type, origin, url }) => ({ name, path: file, video_type, origin, url })),
|
|
12360
|
+
index_url: "https://vidfarm.cc/experimental"
|
|
12361
|
+
});
|
|
12362
|
+
}
|
|
12363
|
+
const bases = all.filter((entry) => entry.origin === "builtin");
|
|
12364
|
+
const experimental = all.filter((entry) => entry.origin === "experimental");
|
|
12365
|
+
console.log(`${DIM}Base harnesses — copy one next to your work, then edit it:${RESET}`);
|
|
12366
|
+
for (const entry of bases) {
|
|
12352
12367
|
console.log(` ${GREEN}${entry.name}${RESET} ${DIM}${entry.video_type ?? ""}${RESET}`);
|
|
12353
12368
|
}
|
|
12369
|
+
if (experimental.length) {
|
|
12370
|
+
// The same shelf as https://vidfarm.cc/experimental, shipped in the package
|
|
12371
|
+
// so an agent reads a full format contract by name without a fetch.
|
|
12372
|
+
console.log(`\n${DIM}Format harnesses — complete contracts for ONE format. Read one before you build it:${RESET}`);
|
|
12373
|
+
for (const entry of experimental) {
|
|
12374
|
+
console.log(` ${GREEN}${entry.name}${RESET} ${DIM}${(entry.video_type ?? "").slice(0, 120)}${RESET}`);
|
|
12375
|
+
}
|
|
12376
|
+
console.log(`${DIM}vidfarm harness show <name> (also live at https://vidfarm.cc/experimental)${RESET}`);
|
|
12377
|
+
}
|
|
12354
12378
|
console.log(`\n${DIM}vidfarm harness init <name> --out ./work/${HARNESS_FILENAME}${RESET}`);
|
|
12355
12379
|
console.log(`${DIM}vidfarm harness derive <forkId> (a decomposed template → a harness)${RESET}`);
|
|
12356
12380
|
console.log(`${DIM}vidfarm qa ./work --harness <name|path> (repeatable — harnesses stack)${RESET}`);
|
|
@@ -59,10 +59,10 @@ const DISCOVERY_NAMES = ["HARNESS.md", "harness.md", "QA_REGIME.md", "qa_regime.
|
|
|
59
59
|
// They ship inside the skill pack (.agents/skills/vidfarm/harnesses/) rather
|
|
60
60
|
// than as TS string constants, so a director can read, diff, and copy them as
|
|
61
61
|
// normal files — the file IS the documentation.
|
|
62
|
-
function
|
|
62
|
+
function packDir(...segments) {
|
|
63
63
|
let dir = path.dirname(fileURLToPath(import.meta.url));
|
|
64
64
|
for (let i = 0; i < 6; i += 1) {
|
|
65
|
-
const candidate = path.join(dir,
|
|
65
|
+
const candidate = path.join(dir, ...segments);
|
|
66
66
|
if (existsSync(candidate))
|
|
67
67
|
return candidate;
|
|
68
68
|
const parent = path.dirname(dir);
|
|
@@ -72,32 +72,77 @@ function builtinDir() {
|
|
|
72
72
|
}
|
|
73
73
|
return null;
|
|
74
74
|
}
|
|
75
|
-
|
|
76
|
-
|
|
75
|
+
function builtinDir() {
|
|
76
|
+
return packDir(".agents", "skills", "vidfarm", "harnesses");
|
|
77
|
+
}
|
|
78
|
+
// The EXPERIMENTAL harnesses — full format contracts under live testing, served
|
|
79
|
+
// at https://vidfarm.cc/experimental/<slug>.md. They ship inside the npm package
|
|
80
|
+
// too (`experimental/**/*.md` in package.json `files`), so an agent that already
|
|
81
|
+
// has the CLI reaches them by NAME, offline, with no fetch: `vidfarm harness show
|
|
82
|
+
// meme-recaption`, `vidfarm qa ./work --harness wall-text-pov-ugc`. The web index
|
|
83
|
+
// stays the source of truth for what exists; this is the same shelf, local.
|
|
84
|
+
function experimentalDir() {
|
|
85
|
+
return packDir("experimental");
|
|
86
|
+
}
|
|
87
|
+
function readEntry(full, name, origin) {
|
|
88
|
+
const parsed = parseHarness(readFileSync(full, "utf8"), full);
|
|
89
|
+
return {
|
|
90
|
+
name,
|
|
91
|
+
path: full,
|
|
92
|
+
video_type: parsed.video_type,
|
|
93
|
+
summary: parsed.summary,
|
|
94
|
+
origin,
|
|
95
|
+
...(origin === "experimental" ? { url: `https://vidfarm.cc/experimental/${name}.md` } : {})
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
export function listExperimentalHarnesses() {
|
|
99
|
+
const dir = experimentalDir();
|
|
77
100
|
if (!dir)
|
|
78
101
|
return [];
|
|
79
102
|
return readdirSync(dir)
|
|
80
|
-
.filter((file) => file.endsWith(
|
|
103
|
+
.filter((file) => file.endsWith(".md"))
|
|
81
104
|
.sort()
|
|
82
|
-
.map((file) =>
|
|
83
|
-
const full = path.join(dir, file);
|
|
84
|
-
const parsed = parseHarness(readFileSync(full, "utf8"), full);
|
|
85
|
-
return { name: file.slice(0, -BUILTIN_SUFFIX.length), path: full, video_type: parsed.video_type, summary: parsed.summary };
|
|
86
|
-
});
|
|
105
|
+
.map((file) => readEntry(path.join(dir, file), file.slice(0, -".md".length), "experimental"));
|
|
87
106
|
}
|
|
88
|
-
/**
|
|
107
|
+
/** Both shelves, built-ins first. `vidfarm harness list` prints exactly this. */
|
|
108
|
+
export function listBuiltinHarnesses() {
|
|
109
|
+
const dir = builtinDir();
|
|
110
|
+
const builtins = !dir
|
|
111
|
+
? []
|
|
112
|
+
: readdirSync(dir)
|
|
113
|
+
.filter((file) => file.endsWith(BUILTIN_SUFFIX))
|
|
114
|
+
.sort()
|
|
115
|
+
.map((file) => readEntry(path.join(dir, file), file.slice(0, -BUILTIN_SUFFIX.length), "builtin"));
|
|
116
|
+
return [...builtins, ...listExperimentalHarnesses()];
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Resolve `hooks` (built-in), `meme-recaption` (experimental), or
|
|
120
|
+
* `./my/HARNESS.md` (a path) to a file. Underscore spellings resolve too, so the
|
|
121
|
+
* URL slug and the CLI name never disagree — the same near-miss the web route
|
|
122
|
+
* forgives with its aliases.
|
|
123
|
+
*/
|
|
89
124
|
export function resolveHarnessPath(ref) {
|
|
90
125
|
const direct = path.resolve(ref);
|
|
91
126
|
if (existsSync(direct) && !direct.endsWith(path.sep))
|
|
92
127
|
return direct;
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
128
|
+
const slug = ref.trim().toLowerCase().replace(/\.md$/, "").replace(/_/g, "-");
|
|
129
|
+
const builtins = builtinDir();
|
|
130
|
+
if (builtins) {
|
|
131
|
+
for (const name of [ref, slug]) {
|
|
132
|
+
const candidate = path.join(builtins, `${name}${BUILTIN_SUFFIX}`);
|
|
133
|
+
if (existsSync(candidate))
|
|
134
|
+
return candidate;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
const experimental = experimentalDir();
|
|
138
|
+
if (experimental) {
|
|
139
|
+
const candidate = path.join(experimental, `${slug}.md`);
|
|
96
140
|
if (existsSync(candidate))
|
|
97
141
|
return candidate;
|
|
98
142
|
}
|
|
99
143
|
const names = listBuiltinHarnesses().map((entry) => entry.name);
|
|
100
|
-
throw new Error(`No harness "${ref}". Pass a file path, or one of the
|
|
144
|
+
throw new Error(`No harness "${ref}". Pass a file path, or one of the bundled names: ${names.join(", ") || "(none bundled)"}. ` +
|
|
145
|
+
`The live index is https://vidfarm.cc/experimental. ` +
|
|
101
146
|
`Scaffold your own with \`vidfarm harness init <name> --out ./work/HARNESS.md\`, ` +
|
|
102
147
|
`or derive one from a decomposed template with \`vidfarm harness derive <forkId>\`.`);
|
|
103
148
|
}
|
|
@@ -117,7 +117,8 @@ export const PACK_TOPICS = [
|
|
|
117
117
|
blurb: "The 5-stage ladder — what the viewer knows, what the video must do, and what it may ask for" },
|
|
118
118
|
{ topic: "problem-angles", aliases: ["angle", "lenses", "problem-angle"], doc: "references/content-ideas.md", heading: "The problem angles",
|
|
119
119
|
blurb: "44 angles on the problem — hold the frame, change the angle when a topic is \"already covered\"" },
|
|
120
|
-
{ topic: "meme-recaption",
|
|
120
|
+
{ topic: "meme-recaption", // `meme_recaption` needs no alias: resolvePackTopic folds `_` to `-` first.
|
|
121
|
+
aliases: ["meme", "recaption", "meme-caption"], doc: "references/editor-workflows.md", heading: "Writing a meme recaption",
|
|
121
122
|
blurb: "Recaption a meme at a pain or a win the niche knows — the cold-viewer test. Building one from scratch? the full format is vidfarm.cc/experimental/meme-recaption.md" },
|
|
122
123
|
{ topic: "product-explainer", aliases: ["product-explainers"], doc: "harnesses/product-explainer.HARNESS.md",
|
|
123
124
|
blurb: "The product-explainer harness — the bundled base for explaining what a product does" },
|