Skip to main content
The core loop: create activates instruments on matching devices, tail or get reads what comes back, stop ends it early rather than waiting out --for.

create

Activates instruments on the devices matching a target. The request is live until it expires — devices matching it converge on the instruments named here, the ones already running immediately, the rest the next time they check in.
Hunting a hitch: the default concurrency.mainThreadHang:thresholdMs=2000 only catches full freezes — lower it (250–500) for smaller stutters, and pair it with runtime.stackSamples (what ran) and uikit.view.layoutPass or swiftui.host.updates (why). An idle capture finds nothing — drive the UI during the window.

list

The default when request is run with no subcommand. Lists live requests.

get

Reads the readings a request captured. The stored container is fetched whole and rendered here — the same rendering the dashboard downloads.
At a human terminal, the table renders colored and grouped by launch — a real view-hierarchy tree for viewHierarchy readings, not a flat dump. Piped or scripted, it’s plain JSON.

tail

Prints readings as they arrive, then stops. One reading per line as JSON, so a stream cut short still parses up to where it stopped.
This always ends by itself — a request carries an expiry, so there is no way to start a tail that never returns. Why it ended is written to stderr; the readings are on stdout.

stop

Stops a live request by expiring it now — the teardown mechanism brought forward. Matching devices stop collecting on their next check-in; readings already stored stay readable.
Worth doing the moment a capture answers the question, rather than waiting out the TTL: a live request keeps every matching device instrumenting and holding a place in the presence budget.