Tapes and shots in your repo
Write the keystrokes once, keep them beside the code, and record any shot by name.
What it does
prec runs inside your app's git repository and reads render/terminal.toml at its top. Each shot names its tape, what to launch and how the clip closes. prec builds the app (a cached build per commit), runs its fixture setup and teardown in a clean environment, and renders the working tree or any tag or commit.
A tape holds only steps: text to type and keys to press, each with an optional speed and repeat count. The settings live in terminal.toml, so one tape renders at any size, rate or theme.
-
Wait for the screen, not the clock
Wait /regex/returns as soon as the screen matches, instead of guessing a sleep;Idle 3swaits until the screen, colours and cursor included, has not changed for 3 seconds, as when an agent session finishes. -
Squeeze the spinners
Squeeze 400mscuts every later stretch where no letter on the screen changes, a spinner or a counter, to 400 ms, keeping typed and printed text andSleepat real speed. -
Your data stays out
The pty starts from a clean environment with a scratch
HOME.pass_envhands named variables to the app, and the cast lists the names, never the values. Before a replay, prec refuses a picture showing your home path, hostname, user name, an email or a passed value. -
Masks in every frame
maskfills each regex match on the screen, wherever and whenever it shows, and each block of cells with the theme's background in every frame, written into the cast so every replay covers it.
Measured
How to use it
-
Describe the app and its shots in
render/terminal.toml.app = "myapp" bin = "myapp" grid = [120, 34] frame = "bare" setup = "{bin}/myapp-fixture >/dev/null" teardown = "myapp server --stop || true" [build] command = "cargo build --release --locked --bin myapp --bin myapp-fixture" bin_dir = "{target}/release" [env] MYAPP_DATA = "{scratch}/data" MYAPP_NOW = "2026-09-29T10:00:00Z" [theme] background = "#eff1f5" foreground = "#4c4f69" [shots.tour] kind = "clip" line = "The terminal workspace stepping through its views" tape = "render/terminal/tour.tape" launch = "myapp tui" settle = "3s" closure = "palindrome" -
Write the tape. This is the sample app's
typing.tape.Sleep 300ms Type "demo tick" Enter Sleep 1.6s Type "demo show" Enter Sleep 1.2s -
List the shots, then record one.
prec shots myapp prec clip myapp tour --size 1080p --fps 60 -
Try it in a checkout of prec, on its sample app, once
prec doctorfinds Chromium and the fonts.prec clip demo typing --app-dir examples/demo --size 720p --fps 30