Watching a collection run
For the complete documentation index, see llms.txtAn agent that starts a collection in the background —
npx @unotest/web collection smoke &— sees the CLI’s per-scenario lines only when the process ends, because a piped stdout is block-buffered. The run’s own journal is the progress source. It is written line by line as the run goes:
unotest/.runs/<yyyy>/<mm>/<dd>/col-<name>-<id>/steps.jsonl.runs becomes .runs.<env> for a --env <name> run; the date shard is
UTC. col-<name>- is the collection run’s id prefix and the <id> tail is a
timestamp plus random hex, so take the newest directory with that prefix once
the run has started.
The events
One JSON object per line, four kinds:
kind | Fields | When |
|---|---|---|
collection-run:started | runId, collection, scenarios[] (in order) | before the first scenario |
collection-run:scenario-started | scenario, scenarioRunId | each scenario takes a worker |
collection-run:scenario-finished | scenario, scenarioRunId, outcome | completed / failed / aborted / interrupted |
collection-run:finished | outcome | the run is over — nothing follows |
Every line also carries t (epoch ms). scenarioRunId names the scenario’s
own run directory under the same .runs root, where its steps.jsonl and
failure bundle live. A line that does not parse
is the one being written — retry on the next read, never treat it as the end.
tail -f unotest/.runs/2026/09/03/col-smoke-*/steps.jsonl \ | jq -c 'select(.kind | startswith("collection-run:scenario")) | {kind, scenario, outcome}'A contract, not an implementation detail
The event types (CollectionRunArtifact) and the file name (STEPS_FILE)
are exported from @unotest/protocol under semver, and the box daemon reads
the same events for its metrics. Build on them.