Local results viewer
Browse local results in the browser.
After the whole dataset finishes, or after a single task, use Viewer for scores, trajectories, and copyable commands. Jobs reads that package's .ageval/suite-runs/ and .ageval/runs/. Browsing stays on those files. Sharing an opened suite or job uploads a read-only snapshot; see Snapshot share.
From the Jobs table you can delete a local Job after a path preview. Deleting a suite row also deletes the runs it references; they do not come back as singles. You cannot delete one run from inside a suite. That wipes local results, not a Registry object (ageval results delete is different). Same command: ageval jobs delete --local <dataset> --job <id> --yes.
Pin and notes stay in this browser only. They are not written to evidence, lock, or Registry.
Open
cd apps/viewer && pnpm install && pnpm build && cd ../..
ageval view examples/datasets/minimal-demo
# or
ageval view examples/datasets/minimal-demo --no-browser --port 8765
# Cached Hub ref (a unique hit does not contact Hub)
ageval view official/demo@0.1.0
# Dev: one command (starts Vite when possible; otherwise prints fallback)
ageval view examples/datasets/minimal-demo --dev --port 8765
# Deep-link the run you just finished
ageval view examples/datasets/minimal-demo --open /jobs/<id>
# Every dataset root sitting in this directory
ageval view examples/datasets --no-browserA dataset root or a cached registry ref opens that one package. A directory that is not itself a dataset keeps only the child folders whose ageval.yaml is ageval.dataset/1. Other children are skipped, and an empty directory still opens.
The header is Datasets, Jobs, Agents, and Plugins. More than one dataset lands on Datasets. One dataset lands on Jobs. Jobs shows only the package you pick. Agents and Plugins list the packages shipped with the CLI, plus packages installed under your ageval home. Opening a row is read-only: README when the package has one, the manifest, profiles.yaml when present, and a file tree. A plugin row also shows the extension points that package declares. Run results stay on Jobs.
On Datasets, Jobs, Agents, and Plugins, search and filters stay at the top of the scrolling column. Dataset tables split on the organization in dataset_id. Plugin and Agent tables show the description; source stays a filter beside search. A file whose name contains env and ends in .example, .sample, .template, or .dist previews as text, including .env.example. .env, .env.local, .env.production, and other .env.* files stay hidden. A path segment named credentials is not served.
ageval view --dev talks to the same local API and starts Vite when it can. If it cannot, it prints pnpm --dir apps/viewer dev. Two-process contract: API port (default 8765) + UI port (default 5173). Production ageval view serves apps/viewer/dist/.
Layout
Jobs → Tasks → Attempt
| Layer | Content |
|---|---|
| Jobs | Local results for the whole dataset, and for a single task (Kind: suite / single). Kind / Source are filters; suite Source lists task ids only. Pass rate and Mean score are the score columns; the dataset is the one you already picked. When Kind is suite, switch Table / Pareto / Waffle. Pareto axes are cost, tokens, or time. A waffle square is one trial. The chart is observational |
| Tasks | Per-task status / score, and average duration from each attempt's phase timing. A task that has not run leaves duration blank. A suite task with one run opens that run directly |
| Attempt | Outcome, Timing (and Tokens when present), actors, evidence tabs. A fork shows a fork tag after the model name; the trajectory draws a cut after the inherited prefix |
Dataset, Kind, Source, harness, model, and the suite chart are part of the address. Back returns to that selection. With Kind set to suite, the count is finished jobs over the jobs in the filter, and the Trials column stays visible.
Opening a suite shows finished tasks over the total, and a time-left estimate from recent task durations, above the task table. The table is paged. The duration plot still includes every task.

Timing comes from Attempt phase_timing (environment / run / evaluate / record / cleanup); hover bar segments for durations.
Trajectory steps follow the sealed file order: a thought, then the tools that thought invoked, then the next thought. When a sealed step (thought, tool_call, or final assistant) carries elapsed_ms, the step header shows that duration. Missing timing is omitted — Viewer does not invent it from file mtimes or the page clock. The Trajectory tab can filter steps by kind. Once the trajectory has scrolled into view, a rail on the right jumps to a step.

Each tool-call row (and other long rows) can collapse; the observational PASS note has expand-all / collapse-all, same as the Hub Attempt page.
Verifier: When both evaluation/observation.jsonl and evaluation/checks.json are present, a Trajectory / Files toggle sits on the far right of the tab row (trajectory first). Otherwise the tab shows the one surface that exists. Selecting checks.json in the file tree renders the checkpoints in the preview (counts, expandable rows, stdout/stderr, package script). There is no separate Checks panel. The Agent Trajectory tab still reads only root trajectory.jsonl. A replay Attempt shows a replay chip after the model name. Its trajectory is the source task text plus the actions executed in the fresh environment and their new observations.
When analysis/<analyzer>/report.json exists, the Attempt page adds an Analysis evidence tab (stats, hack, or review). The tab is omitted when no report is present. Those reports are observations. They do not change PASS or evaluation/checks.json. Hub does not upload them.
Browsing does not read Registry. The share control on an opened suite or job uploads a snapshot. Remote catalogs stay on the Hub.