Skip to content
tomo-labs

CLI reference

Every lab command and flag, and every environment variable it reads.

lab <command> [args]

lab is one binary with a small command set. All logic lives in pkg/lab; cmd/lab is a thin front end, so the same harness can be embedded as a library.

build

lab build [tool] [--no-cache]

Builds the shared base image, the trace proxy image, and every wired tool image. Pass a tool name to build just that one. Only needs to rerun after a Dockerfile changes.

--no-cache forces every image to build from scratch, ignoring cached layers. Use it after a version bump: the runtime keys a RUN npm install pkg@${VERSION} layer on the command string, not the resolved version, so bumping the pin alone reuses the old install. A no-cache build reinstalls at the new pin.

go run ./cmd/lab build codex --no-cache    # reinstall codex at its current pin

run

lab run [tool] [scenario]

Runs scenarios through the worker pool. With no arguments, every tool against every scenario. With a tool, that tool against every scenario. With both, just that pair.

go run ./cmd/lab run tomo                        # tomo, every scenario
go run ./cmd/lab run tomo 03-bugfix-fizzbuzz      # tomo, one scenario

-p, --prompt, prompt

lab -p "<prompt>" [tool...]

Runs one ad-hoc prompt through every tool, or through the tools named after it, and prints a comparison. Goes through the same worker pool as a graded sweep, so its timing is representative.

go run ./cmd/lab -p "explain this repo in one line"
go run ./cmd/lab -p "explain this repo in one line" tomo codex

tools

lab tools

Lists every wired tool, one per line.

scenarios

lab scenarios

Lists every scenario with its one-line description.

prompts

lab prompts <tool> [scenario] [--json] [--brief]

Recovers a tool's system prompt from its captured traces. It reads the request tap across every run in scope, unions the distinct system prompts, groups the per-run renderings that differ only in volatile spans like the date or a session id, and ranks the agent's working prompt, the one carrying a tool schema, first. Pass a scenario to scope to one; omit it to union every run. --json emits the structured form, the same shape the prompts pages are generated from; --brief keeps the per-prompt headers and drops the full text.

go run ./cmd/lab prompts tomo                 # every run, full text
go run ./cmd/lab prompts codex --brief         # headers only
go run ./cmd/lab prompts opencode --json       # structured, for regenerating a docs page

gen

lab gen [--limit N] [--all] [--langs a,b] [--no-validate]

Materializes a public benchmark into the active suite's tasks/ dir, chosen with the global --suite flag. It fetches the upstream benchmark, renders each problem into the harness task shape, and proves each task against a known-good solution before keeping it, so a task that cannot be validated never lands. --limit N takes N problems per track, --all takes the whole benchmark, --langs a,b selects language tracks for aider or datasets for evalplus, and --no-validate skips the reference-solution proof for a quick inspection. See evals.

meta

lab meta

Captures each wired tool's version and release date into tool.json, checked against the tool's own npm or module registry rather than a version pinned by hand. Run this after building a tool so the results table never drifts from what actually ran.

report

lab report [--json]

Reads every run ever captured for every tool and prints a comparison table: pass rate, tokens, latency, memory, install footprint, and more. --json prints the same summary as JSON instead of a table.

reparse

lab reparse

Recomputes the metrics of every captured run from its stored trace, without rerunning any agent. Use it after a change to how a metric is derived, so old runs are scored the same way as new ones.

clean

lab clean

Removes lab containers and dangling images left behind by builds and runs.

--suite

lab <command> --suite <name>

Any command that runs, lists, reports, or generates over tasks takes --suite to select an eval tier instead of the core scenarios/. A suite reads its tasks from evals/<name>/tasks/ and lands results in a separate tree, so a tier never mixes into the core report. lab gen --suite <name> materializes a tier; see evals.

go run ./cmd/lab run tomo --suite aider
go run ./cmd/lab report --suite evalplus

Environment

Every knob has an environment fallback, so a run reproduces regardless of which front end starts it.

Variable Default Meaning
OPENCODE_API_KEY Upstream key, forwarded to the tool under test, never written to a trace.
LAB_MODEL deepseek-v4-flash-free Bare upstream model id.
LAB_UPSTREAM https://opencode.ai/zen OpenAI-compatible base the proxy forwards to.
LAB_DATA $HOME/data Where traces and results land, per tool/scenario/timestamp.
LAB_ROOT repo root Root holding scenarios/ and tools/.
LAB_MAX_TURNS 12 Agent turn budget handed to the tool.
LAB_ATTEMPTS 1 Capability tries before a scenario is called failed. 1 is pure pass@1; higher turns on opt-in best-of-N.
LAB_ATTEMPT_TIMEOUT 900 Per-attempt scored wall-clock ceiling in seconds. A timeout grades the partial work and never creates an extra pass@1 attempt. 0 disables it.
LAB_PREP_TIMEOUT 300 Task-environment preparation ceiling in seconds. A timeout starts the agent with the partial or bare environment and does not consume model time. 0 disables it.
LAB_PROXY_PORT 8899 Host port the first worker's proxy publishes; later workers take the next ports.
LAB_KEEP_RUNS 5 How many timestamped runs to keep per tool/scenario. 0 keeps all.
LAB_CONCURRENCY 3 How many tool/scenario runs to keep in flight at once.
LAB_RUNTIME auto-detected Force docker or podman instead of detecting which is present.

Nothing here is invented. If a flag or variable is not on this page, lab does not read it.