make
Drive the app in real time and deliver the master plus its working directory.
open-take make --plan plan.json --out demos/myapp.mp4make drives the app (real time) and delivers the polished master at exactly
--out, with the working directory beside it: the editable
composition.json, plus the kept capture.mp4 and capture.json — the
raw footage and the ground-truth event log every later re-render builds on.
The raw capture auto-opens the moment it lands — minutes before the polished
render finishes — so the wait is spent watching footage, not a spinner
(--no-open to skip).
In practice the plan is authored by your agent from the skill's editorial
loop; --plan is the contract between that plan and the camera.
The pre-capture target check
Before a single frame is recorded, every plan target is resolved against the
page as loaded, with the capture's own locator semantics — and only the field
the capture will actually read (text beats selector for a click; a
scroll reads toSelector first).
Two findings refuse the shoot in seconds, before anything is recorded: a target in the plan's cold prefix that doesn't exist, and a selector the page rejects as invalid CSS.
A third is the parse-intent mismatch: a by-text target that resolves — but
to a different element than the one inside main carrying that name. Each
action searches its own candidate set (a click sees only clickables; a scroll
also sees headings and paragraphs) and matches an exact name first, then a
substring — so a headline's words can land on whatever element merely contains
them, classically a sidebar thumbnail that navigates away. This refuses the
shoot only in the shape that is a certainty: a cold-prefix target whose
substring match sits outside main, covering only a sliver of the picked
element's actual name, while the named element is inside main. Every other
mismatch — an exact-name match, an abbreviated label ("Comments" naming a
"Comments3" badge button), a landing inside main, anything after the cold
prefix — is a warning, and the capture proceeds.
Targets that only exist after earlier steps reveal them aggregate into one advisory; if one never appears, the skipped step fails the run at capture time.
The defects block (exit 2)
Every defective verdict — a structural lint error, a pre-capture refusal, a
skipped step, a post-shoot check error — exits 2 and prints a machine-readable
report: one JSON object between --- open-take defects v1 --- and
--- end open-take defects ---, also written to <name>.take/defects.json
when the take dir exists (a refusal never creates the dir, and only writes
into one that belongs to this plan's app — the stdout block is always the
authority). Each entry names the gate that measured it
(plan-lint · precheck · capture · post-shoot · composition), the
severity, the field path, the measured values, and — wherever the engine can
compute one — the exact fix. Warnings ride along: the late-bound target
the gate cannot refuse surfaces only there.
The block is a repair contract, not a log: relay it verbatim to whatever authored the plan, take back the entire corrected plan, and re-run — at most twice, then stop and hand the final block to a human. The skill spells out the loop; the engine never calls a model, it only judges.
Overwrite safety
make refuses to overwrite a take that was shot from a different app —
two demos in one folder each get their own name (--out myapp.mp4). The
honest case, same app on a new dev-server port, is --force.
Flags
| flag | default | notes |
|---|---|---|
--out <path> | demos/take.mp4 | non-mp4 extensions are refused; a bare name is completed |
--fps <n> | 60 | capture and render fps; 30 for fast drafts |
--capture-scale <n> | 2 | Retina capture — drop to 1 if a heavy page can't hold fps |
--draft | — | fast draft render of the delivery |
--no-strict | — | exit 0 even when plan steps were skipped or a post-shoot check failed — by default those exit non-zero (the summary lists them either way) |
--profile <name> | — | authenticated session from auth |
--headed | — | visible Chrome window; the screencast records the page either way |