cmux shot writes a png or a jpeg of a cmux window. cmux record writes an mp4
or a gif of one. Both capture only cmux's own windows, both go through the
same permission-free path, and both work in a release build and inside CI. No
Screen Recording permission is involved and none is ever requested.
cmux shot --label settings-sheet # png of the frontmost window
cmux shot --jpg --max-width 1200 --out ~/before.jpg
cmux record start --gif --max-seconds 8 --label sidebar-drag
cmux record note "dragging the workspace" # caption, drawn into the clip
cmux record stop
shot prints <width>x<height> <bytes> <path>. record prints
<id> <state> <frames> <path>. Both take --json for the whole response.
Which one
Take a screenshot when the thing is still: a sheet, a menu, a layout, a label, a color. Record when the thing is a change over time: a drag, an animation, a reorder, two views settling in an order, a spinner that should stop. A screenshot of a drag shows nothing, and a clip of a static sheet is a large file a reviewer has to click to play.
Working from a clip to a still
--region x,y,w,h is the same rectangle in both commands, in window points from
the window's top left. So a detail noticed in a clip can be shot with the same
four numbers:
cmux record start --region 0,0,420,900 --max-seconds 6 # watch the sidebar
cmux shot --region 0,0,420,900 --label sidebar-final # keep the end state
Notes for an agent recording its own cmux
- A recording stops itself at
--max-seconds(default 15, maximum 120), so a clip is never left running by an agent that stops paying attention. Set it above the time the actions take or the clip ends early. - One at a time. A second
record startis refused withconflictwhile one is running.cmux record listsays whether anything is going, andcmux record statusreports the frame count, with the effective frame rate in--json. - Caption as you go.
cmux record note "<text>"draws text into the clip from that moment on. A clip has no step list beside it, so one note before each thing a reviewer should notice is worth more than a longer clip.--no-captionsturns them off. - The clip is only cmux. Another app in front of the cmux window does not appear in the frames, so a capture does not have to own the screen.
- Frames are timed by when they were captured, so a clip plays at the speed
things happened even when the sampler fell behind the requested rate. Check
fps_effectivein--jsonif a clip looks slower than expected. - A
gifis the shape to paste into a pull request, and--gifalready picks the 8 fps and half scale that keep one small; an mp4 is sharper and needs a click to play.scripts/pr-media.pyuploads either and converts an mp4 to a gif on the way. - Neither command replaces a directory or destroys an existing file before the
new one is closed.
--outon a path that is not a file is refused, and so is one whose extension does not match the format:--out clip.gifneeds--gif.
In a CI dogfood tour
A dogfood scenario records with a record step wrapping the steps that matter,
and captions with note, rather than by calling the CLI. The step table and the
options are in
cmux-testing/references/dogfood-scenarios.md.
Deep-dive references
| Reference | When to use |
|---|---|
| references/commands.md | Every flag, the response shape, the error codes, window selection, limits |