sanderling replay

Local web UI for exploring runs produced by sanderling test. Reads runs/<id>/meta.json and runs/<id>/trace.jsonl from disk.

sanderling replay [run-or-runs-dir] [--port N] [--no-open] [--dev]

The positional argument can be a runs directory or a single run directory (auto-detected by meta.json). Defaults to ./runs.

sanderling replay

Panels

Panel What it shows
Screenshot Device screenshot for the focused step, with the dispatched action's target spotlit.
ActionList Ordered list of steps with the verb and target for each action.
Timeline Per-property lane chart over the run; cells coloured by violated, pending, or holds.
ViolationsPanel Property statuses at the focused step with residual formulas for any that failed.
HierarchyPanel Filterable table of every UI element captured at the focused step; mirrors the selectors documented in Spec language reference.
SnapshotTable Flattened snapshots map for the focused step, with diffs against the previous step.
MetricsChart Heap and other host-side metrics sampled per step.
ExceptionsPanel Uncaught exceptions captured during the run, with a jump-to-first control.

Keyboard shortcuts

Key Action
j, Right Next step
k, Left Previous step
Shift+j, Shift+Right Jump 10 forward
Shift+k, Shift+Left Jump 10 back
g / G First / last step
. Next step with a violation

Arrow keys inside a tablist or listbox yield to those widgets. Use j/k when focus is on one.

/runs/:id/steps/:n links to a specific step. Use it in issues or PRs when pointing at a violation.

The run index auto-refreshes over SSE as new runs land, so sanderling replay and sanderling test can run side by side.

Development

Two-process loop while iterating on the UI:

make web-dev     # bun + vite on http://127.0.0.1:5173
make replay-dev  # sanderling replay --dev, proxies non-API to 5173

Single binary with the bundle embedded:

make sanderling