Physics & Foundation Models
Four Tier-4 groups wrap the physics engines and the foundation-model stacks — physics,
warp, groot and cosmos — plus scene reconstruct,
which hands a capture to a neural-reconstruction CLI. Caasi implements none of them: every command
resolves an upstream tool from the catalog, starts it as a tracked run, and — when nothing is
installed — fails honestly and names the config key that would point at it.
| Group | Catalog domain | Commands | What it delegates |
|---|---|---|---|
caasi physics | physics — kind sim, tool isaacsim | status · list · run · benchmark | PhysX, Newton, Warp, MuJoCo, Gazebo: a launcher choice plus CAASI_PHYSICS_ENGINE. |
caasi warp | warp — kind python | status · test · benchmark | NVIDIA Warp: a device probe in a subprocess, your benchmark script as a run. |
caasi groot | groot — kind python, tool groot | status · setup · run · train · evaluate | The Isaac GR00T repo's own installer, module and scripts, through its own interpreter. |
caasi cosmos | cosmos — kind python | status · run · dataset | The Cosmos CLI (or -m cosmos_predict1) with your arguments forwarded verbatim. |
caasi scene reconstruct | capability nurec of usd | — | A NuRec CLI that turns a capture into OpenUSD. |
Shared conventions:
- every command of the four groups takes
--json(scene reconstructtakes only--dry-run); - every verb that starts something takes
--dry-run, and all of them butscene reconstructtake--name; whatever Caasi does not recognize is forwarded to the upstream tool — a trailing--is optional; - capability probes run in the order package → binary → module → env → path, first hit wins, and a capability marked core reports missing when absent while an optional one reports absent;
- every upstream name is catalog data:
caasi config set catalog.<domain>.<capability>.<field> <value>(see caasi config).
caasi physics
The physics “interface” is deliberately thin: a launcher choice and one environment
variable, nothing more. Caasi picks the engine the catalog resolves, exports
CAASI_PHYSICS_ENGINE=<engine> to the run, and — when that engine ships its own
launcher script — swaps it into the command's first position. PhysX runs through Isaac Sim's
python.sh; Newton runs through the Newton launcher when one exists
(isaac-sim.newton.sh, shipped next to python.sh). Five engines are
known:
| Engine | Detected via | Core | Launcher used |
|---|---|---|---|
physx | paths extsPhysics/*physx*, exts/omni.physx* under the Isaac Sim root | yes | the experiment's own (Isaac Sim python.sh) |
newton | path isaac-sim.newton.sh; modules newton-physics, newton | no | isaac-sim.newton.sh when it resolved as a .sh path |
warp | modules warp, warp-lang | no | the experiment's own |
mujoco | module mujoco | no | the experiment's own |
gazebo | binaries gz, gazebo | no | the experiment's own |
caasi physics status
caasi physics status [--json]
Reports the five engines plus the engine that would be used by default (physics.default,
else physx). On a machine with no Isaac Sim this is the real output:
shellcaasi physics status
Physics Engines
Engine physx
Capability State Detail
physx missing not installed
newton absent not installed
warp absent not installed
mujoco absent not installed
gazebo absent not installed
0 of 5 capabilities installed.
The core capability shows missing, the optional ones
absent; exit 0 — this is a report, not a gate. The
Root and Launcher rows appear only once Isaac Sim is registered in the
tool registry (or ISAACSIM_PATH is set),
because the physics domain is a sim domain and has no Python fallback:
shellcaasi physics status
Physics Engines
Root /opt/isaac-sim-6.0
Launcher /opt/isaac-sim-6.0/python.sh
Engine physx
Capability State Detail
physx installed /opt/isaac-sim-6.0/extsPhysics/omni.physx
newton installed /opt/isaac-sim-6.0/isaac-sim.newton.sh
warp absent not installed
mujoco absent not installed
gazebo installed /usr/bin/gz
3 of 5 capabilities installed.
JSON carries the standard status payload (domain, kind,
tool, root, total, installed,
capabilities, launcher, running) plus this group's own
engine key:
shellcaasi physics status --json | jq '{domain, kind, tool, root, total, installed, engine, running}'
{
"domain": "physics",
"kind": "sim",
"tool": "isaacsim",
"root": null,
"total": 5,
"installed": 0,
"engine": "physx",
"running": []
}
caasi physics list
caasi physics list [--json]
The engine table with the how of each detection — package,
binary, module, env or path — and the default
engine note:
shellcaasi physics list
Engine State Found via Detail
physx • — not installed
newton • — not installed
warp • — not installed
mujoco • — not installed
gazebo • — not installed
Default engine: physx — change it with: caasi config set physics.default <engine>
On a machine with Isaac Sim registered the same command reports the path detections
from the install tree (physx under extsPhysics/, newton
through isaac-sim.newton.sh) and any gz/gazebo binary as
binary. In the JSON payload the per-engine launcher is set only for an
engine that resolves to a launcher script of its own — newton:
shellcaasi physics list --json | jq '.default, .engines[1]'
"physx"
{
"engine": "newton",
"installed": true,
"how": "path",
"value": "/opt/isaac-sim-6.0/isaac-sim.newton.sh",
"launcher": "/opt/isaac-sim-6.0/isaac-sim.newton.sh"
}
JSON shape: {"domain", "default", "engines": [{"engine", "installed", "how", "value",
"launcher"}]} — how, value and launcher are
null for an engine that was not detected. Always exits 0.
caasi physics run
caasi physics run CONFIG_PATH [--engine KEY] [--name NAME] [--dry-run] [--json] [ARGS…]
| Parameter | Kind | Type | Default | Description |
|---|---|---|---|---|
CONFIG_PATH | argument | path | required | Experiment YAML (.yaml/.yml) — the same file sim run consumes; extra arguments pass through to it. |
--engine | option | str | physics.default, else physx | Physics engine to use: physx, newton, warp, mujoco, gazebo. |
--name | option | str | experiment name | Name for the tracked run. |
--dry-run | option | flag | off | Print the command without starting it. |
--json | option | flag | off | Emit the run record as JSON. |
| trailing args | pass-through | Appended to the script's argv, after --headless when the experiment declares it. |
What happens, in order:
- The experiment YAML is loaded. A missing file is an
honest failure — even for
--dry-run. - The engine is picked:
--engine→physics.default→physx. An unknown key or an engine that is not detected on this machine fails and names the catalog key that would point at it. - The command is built from the experiment (backend
sim,laborpython) and the engine is applied:CAASI_PHYSICS_ENGINE=<engine>in the environment, plus the engine's launcher in first position when it has one. --dry-runprintscommand,cwdandengine; otherwise a detached run (kind: run, the experiment's backend) is started and its manifest records the experiment path and the engine.
shellcaasi physics run /tmp/nope.yaml --dry-run
Error: experiment config not found: /tmp/nope.yaml
exit code: 1
caasi physics run experiments/stack_cubes.yaml --dry-run
Error: 'physx' is not available (extsPhysics/*physx*, exts/omni.physx*). Install it, or point Caasi at the renamed upstream with `caasi config set catalog.physics.physx.paths [...]`.
exit code: 1
caasi physics run experiments/stack_cubes.yaml --engine nope --dry-run
Error: Unknown physics engine 'nope'. Known: physx, newton, warp, mujoco, gazebo
exit code: 1
On a machine where the engines resolve, the dry run shows the launcher that each engine
brings — python.sh for PhysX, isaac-sim.newton.sh for Newton:
shellcaasi physics run experiments/stack_cubes.yaml --dry-run
Dry run — nothing was started:
command: /opt/isaac-sim-6.0/python.sh /home/you/demo/scripts/stack_cubes.py --steps 1000 --headless
cwd: /home/you/demo/experiments
engine: physx (CAASI_PHYSICS_ENGINE)
caasi physics run experiments/stack_cubes.yaml --engine newton --dry-run
Dry run — nothing was started:
command: /opt/isaac-sim-6.0/isaac-sim.newton.sh /home/you/demo/scripts/stack_cubes.py --steps 1000 --headless
cwd: /home/you/demo/experiments
engine: newton (CAASI_PHYSICS_ENGINE)
caasi physics run experiments/stack_cubes.yaml --engine newton --name newton-stack
Started run 20260907-211734-newton-stack.
Follow it with: caasi logs 20260907-211734-newton-stack -f
caasi physics benchmark
caasi physics benchmark CONFIG_PATH [--engine KEY] [--name NAME] [--dry-run] [--json] [ARGS…]
Exactly physics run with kind: benchmark and one extra line after
launch — the reminder that the run's stdout can be parsed for metrics
(caasi benchmark report):
shellcaasi physics benchmark experiments/stack_cubes.yaml --dry-run
Error: 'physx' is not available (extsPhysics/*physx*, exts/omni.physx*). Install it, or point Caasi at the renamed upstream with `caasi config set catalog.physics.physx.paths [...]`.
exit code: 1
# on a machine where the newton engine resolves:
caasi physics benchmark experiments/stack_cubes.yaml --engine newton --name newton-bench
Started run 20260907-211734-newton-bench.
Follow it with: caasi logs 20260907-211734-newton-bench -f
When finished: caasi benchmark report 20260907-211734-newton-bench
caasi config set physics.default <engine> changes the engine used when
--engine is absent. caasi config set physics.engines.<engine>.launcher
<path> overrides the launcher for one engine — an absolute path, or a path relative
to the Isaac Sim tool root, e.g. caasi config set physics.engines.newton.launcher
isaac-sim.newton.sh. A launcher that is not a file is ignored, and an engine detected
through a .sh path uses that path. The run's environment always carries
CAASI_PHYSICS_ENGINE=<engine> so the experiment can branch on it. Caasi never
imports a physics engine.
caasi doctor --component physics
The same probes as one doctor section,
Physics Engines. physx is the only core capability, so it is the only row
that can fail (exit 1); every other engine is optional and is
skipped. The warp domain reports into this section too, which is why
Warp appears here as well as under caasi warp:
shellcaasi doctor --component physics
Environment Diagnostics
Physics Engines
✗ PhysX — not found (extsPhysics/*physx*, exts/omni.physx*)
↳ Install it, or point Caasi at the renamed upstream with `caasi config set
catalog.physics.physx.paths [...]`.
• Newton — not found (newton-physics, newton, isaac-sim.newton.sh)
• Warp — not found (warp, warp-lang)
• MuJoCo — not found (mujoco)
• Gazebo — not found (gz, gazebo)
✘ 1 issue(s) found, 0 warning(s). Run with --verbose for hints.
exit code: 1
caasi doctor --component physics --json | jq '{summary, exit_code}'
{ "summary": { "fail": 1, "skip": 4 }, "exit_code": 1 }
caasi warp
One capability — warp in the warp domain, detected through the modules
warp / warp-lang, and marked core. Caasi never imports Warp
in-process: test runs a probe in a subprocess and benchmark
starts your script as a detached run. The interpreter is the physics domain's launcher — Isaac
Sim's python.sh when a tool is registered (Warp ships inside the Isaac Sim install,
so its interpreter is the one that can see it), otherwise the CLI's own Python.
caasi warp status
caasi warp status [--json]
The capability plus the interpreter that test and benchmark would
use, as the Launcher row (JSON key launcher):
shellcaasi warp status
NVIDIA Warp
Launcher /home/you/demo/.venv/bin/python3
Capability State Detail
warp missing not installed
0 of 1 capabilities installed.
caasi warp status --json | jq '{domain, kind, tool, total, installed, launcher, running}'
{
"domain": "warp",
"kind": "python",
"tool": null,
"total": 1,
"installed": 0,
"launcher": "/home/you/demo/.venv/bin/python3",
"running": []
}
With Isaac Sim registered the Launcher row becomes its python.sh —
that is the interpreter Warp is looked for in.
caasi warp test
caasi warp test [--json]
The real proof: a subprocess runs
import warp; warp.init(); print(warp.get_devices())
with a 120-second timeout (the first init can compile kernels). The capability is
resolved first, so a machine without Warp gets an honest failure instead of a Python traceback:
shellcaasi warp test
Error: No warp capability is installed. Install it, or point Caasi at the renamed upstream with `caasi config set catalog.warp.<capability>.<field> [...]`.
exit code: 1
# with Warp installed, the probe runs in a subprocess:
caasi warp test
Warp initialized. Devices:
['cpu', 'cuda:0']
If the probe itself fails, the last line of its stderr (or stdout) is reported:
Error: Warp test failed: <detail> (exit 1). JSON always carries the
whole probe — {"domain", "python", "returncode", "devices", "stdout", "stderr"} —
with devices being the non-empty stdout lines, and exits 0 only when the
subprocess did:
shellcaasi warp test --json | jq '{python, returncode, devices}'
{
"python": "/opt/isaac-sim-6.0/python.sh",
"returncode": 0,
"devices": ["['cpu', 'cuda:0']"]
}
caasi warp benchmark
caasi warp benchmark [--name NAME] [--dry-run] [--json] [ARGS…]
A pure pass-through: the command is [<resolved interpreter>, ARGS…], so
ARGS must say what to run — a script path or -m <module>. Caasi
adds no Warp flags of its own, and with nothing to run it refuses rather than guessing:
shellcaasi warp benchmark
Error: Nothing to benchmark — pass a script or `-m <module>`, e.g. `caasi warp benchmark bench.py`.
exit code: 1
caasi warp benchmark benchmarks/warp_bench.py --dry-run
Dry run — nothing was launched:
command: /home/you/demo/.venv/bin/python3 benchmarks/warp_bench.py
caasi warp benchmark -m warp.tests.test_bench --dry-run
Dry run — nothing was launched:
command: /home/you/demo/.venv/bin/python3 -m warp.tests.test_bench
Launched for real it is a tracked run (backend: python, kind:
benchmark, default name warp) with the benchmark-report reminder:
shellcaasi warp benchmark benchmarks/warp_bench.py --name warp-bench
Started run 20260907-211734-warp-bench.
Follow it with: caasi logs 20260907-211734-warp-bench -f
When finished: caasi benchmark report 20260907-211734-warp-bench
caasi run status warp-bench --json | jq '{id, backend, kind, status}'
{
"id": "20260907-211734-warp-bench",
"backend": "python",
"kind": "benchmark",
"status": "succeeded"
}
Metrics are parsed from the run's stdout by
caasi benchmark report — Caasi does not
interpret them itself.
caasi groot
Isaac GR00T is a repository, not a package Caasi installs: everything here runs the repo's own
installer, module and scripts through the repo's own interpreter. The repository is
discovered as the catalog's repo capability — the GR00T_PATH environment
variable first, then the common paths ~/Isaac-GR00T, ~/gr00t and
~/workspaces/Isaac-GR00T, plus anything you add with caasi config set
catalog.groot.repo.paths [...]. The tools.groot registry entry (falling back to
$GR00T_PATH) supplies the root used for the repo's python.sh and for the
relative script paths:
| Capability | Detected via | Core | Used by |
|---|---|---|---|
repo | env GR00T_PATH; paths ~/Isaac-GR00T, ~/gr00t, ~/workspaces/Isaac-GR00T | yes | every groot command |
module | module gr00t | no | groot run (the default capability) |
train | script scripts/finetune.py under the repo root | no | groot train, groot run --backend train |
evaluate | script scripts/eval.py under the repo root | no | groot evaluate, groot run --backend evaluate |
data | script scripts/data.py under the repo root | no | groot run --backend data |
The three script capabilities carry no probe of their own: they always read
absent in status, but their resolved script path
is what train/evaluate run. An upstream release that moves a file is a
config edit — caasi config set catalog.groot.train.script <path>.
caasi groot status
caasi groot status [--json]
Without the repo there is nothing to delegate to, and the core capability says so:
shellcaasi groot status
Isaac GR00T
Launcher /home/you/demo/.venv/bin/python3
Capability State Detail
repo missing not installed
module absent not installed
train absent not installed
evaluate absent not installed
data absent not installed
0 of 5 capabilities installed.
With GR00T_PATH set (or the repo in one of the common paths) the Root
row appears, the launcher is the repo's own python.sh, and the script capabilities
resolve against that root:
shellcaasi groot status
Isaac GR00T
Root /home/you/Isaac-GR00T
Launcher /home/you/Isaac-GR00T/python.sh
Capability State Detail
repo installed /home/you/Isaac-GR00T
module absent not installed
train absent not installed
evaluate absent not installed
data absent not installed
1 of 5 capabilities installed.
caasi groot status --json | jq '.capabilities[2]'
{
"key": "train",
"label": "catalog.groot.train",
"group": null,
"core": false,
"found": false,
"how": null,
"value": null,
"launch": null,
"script": "/home/you/Isaac-GR00T/scripts/finetune.py",
"nodes": []
}
caasi groot setup
caasi groot setup [--execute] [--name NAME] [--dry-run] [--json]
| Parameter | Kind | Type | Default | Description |
|---|---|---|---|---|
--execute | option | flag | off | Actually run the install steps as a tracked run. |
--name | option | str | groot-setup | Name for the tracked run. |
--dry-run | option | flag | off | Print the steps without executing them — it wins over --execute. |
--json | option | flag | off | Emit machine-readable JSON output. |
The steps are the repo's own: post_install.sh when the repo has one, otherwise
<repo python> -m pip install -e .. By default they are only
printed — installing a foundation-model repo changes environments, so Caasi does not do it
unless you say so:
shellcaasi groot setup
Error: The GR00T repository was not found (GR00T_PATH, ~/Isaac-GR00T, ~/gr00t, ~/workspaces/Isaac-GR00T). Clone it, set GR00T_PATH, or point Caasi at it with `caasi config set catalog.groot.repo.paths [...]`.
exit code: 1
# with the repo present — GR00T_PATH set, or one of the common paths:
caasi groot setup
GR00T install steps (/home/you/Isaac-GR00T) — not executed:
command: /home/you/Isaac-GR00T/post_install.sh
cwd: /home/you/Isaac-GR00T
Execute them as a tracked run with: caasi groot setup --execute
caasi groot setup --json
{
"domain": "groot",
"executed": false,
"command": ["/home/you/Isaac-GR00T/post_install.sh"],
"cwd": "/home/you/Isaac-GR00T"
}
caasi groot setup --execute
Started run 20260907-211738-groot-setup.
Follow it with: caasi logs 20260907-211738-groot-setup -f
The executed form is a detached run with backend: python, kind: setup
and the repo root in its manifest, so caasi run status latest shows the command that
ran.
caasi groot run
caasi groot run [--backend|-b CAPABILITY] [--name NAME] [--dry-run] [--json] [ARGS…]
Delegates to one capability of the repo — module by default, or whatever
catalog.groot.default names. module becomes
<repo python> -m gr00t ARGS…; any other key becomes
<repo python> <repo script> ARGS…. The working directory is always the
repo root, and the run is recorded with backend: groot, kind: groot:
shellcaasi groot run --dry-run
Error: The GR00T repository was not found (GR00T_PATH, ~/Isaac-GR00T, ~/gr00t, ~/workspaces/Isaac-GR00T). Clone it, set GR00T_PATH, or point Caasi at it with `caasi config set catalog.groot.repo.paths [...]`.
exit code: 1
# with the repo present but the gr00t module not installed:
caasi groot run --dry-run
Error: 'module' is not available (gr00t). Install it, or point Caasi at the renamed upstream with `caasi config set catalog.groot.module.modules [...]`.
exit code: 1
# a script capability needs no module — only the repo:
caasi groot run --backend train --dry-run
Dry run — nothing was launched:
command: /home/you/Isaac-GR00T/python.sh /home/you/Isaac-GR00T/scripts/finetune.py
cwd: /home/you/Isaac-GR00T
caasi groot run --backend train --name finetune -- configs/a.yaml
Started run 20260907-211734-finetune.
Follow it with: caasi logs 20260907-211734-finetune -f
caasi groot train / caasi groot evaluate
caasi groot train CONFIG_PATH [--name NAME] [--dry-run] [--json] [ARGS…]
caasi groot evaluate CONFIG_PATH [--name NAME] [--dry-run] [--json] [ARGS…]
Both take the config file the GR00T script expects and hand it to the repo's own script through
the repo's own interpreter — scripts/finetune.py for train,
scripts/eval.py for evaluate, each path taken from the catalog. The
config is checked before anything is resolved, the run is detached (backend: groot,
kind: train/evaluate, default name = the config file's stem) and its
manifest records the config path:
shellcaasi groot train /tmp/nope.yaml --dry-run
Error: config not found: /tmp/nope.yaml
exit code: 1
# with the repo present:
caasi groot train configs/gr00t_finetune.yaml --dry-run
Dry run — nothing was launched:
command: /home/you/Isaac-GR00T/python.sh /home/you/Isaac-GR00T/scripts/finetune.py configs/gr00t_finetune.yaml
cwd: /home/you/Isaac-GR00T
caasi groot evaluate configs/gr00t_eval.yaml --dry-run
Dry run — nothing was launched:
command: /home/you/Isaac-GR00T/python.sh /home/you/Isaac-GR00T/scripts/eval.py configs/gr00t_eval.yaml
cwd: /home/you/Isaac-GR00T
caasi groot train configs/gr00t_finetune.yaml --name finetune-v2
Started run 20260907-211734-finetune-v2.
Follow it with: caasi logs 20260907-211734-finetune-v2 -f
A script the repo does not have (or has moved) is reported with the exact key that fixes it:
shellcaasi groot train configs/gr00t_finetune.yaml --dry-run
Error: /home/you/Isaac-GR00T has no scripts/finetune.py. Fix the path with: caasi config set catalog.groot.train.script <path>
exit code: 1
GR00T ships a python.sh of its own, and that is what runs its scripts: the
tools.groot registry entry first, then $GR00T_PATH, then this process'
Python as a last resort. Nothing is installed into the environment Caasi itself runs in.
caasi cosmos
The lowest-priority group and the thinnest one: caasi cosmos resolves a Cosmos
entry point and forwards your arguments to it verbatim. Two capabilities, neither core —
module (cosmos_predict1, cosmos1) and cli
(binaries cosmos, ngc). A CLI found as a binary wins and is run directly
(the run's backend is the binary's basename); otherwise the module is run as
<caasi python> -m <module>. Caasi knows no Cosmos flags and invents none.
caasi cosmos status
caasi cosmos status [--json]
shellcaasi cosmos status
NVIDIA Cosmos
Launcher /home/you/demo/.venv/bin/python3
Capability State Detail
module absent not installed
cli absent not installed
0 of 2 capabilities installed.
caasi cosmos status --json | jq '{domain, kind, total, installed, launcher, running}'
{
"domain": "cosmos",
"kind": "python",
"total": 2,
"installed": 0,
"launcher": "/home/you/demo/.venv/bin/python3",
"running": []
}
caasi cosmos run
caasi cosmos run [--name NAME] [--dry-run] [--json] [ARGS…]
With nothing to forward there is nothing to delegate, and with nothing installed the failure names the key that would point at a CLI:
shellcaasi cosmos run
Error: Nothing to forward — pass the arguments for the Cosmos CLI, e.g. `caasi cosmos run <args>`.
exit code: 1
caasi cosmos run predict --dry-run
Error: No cosmos capability is installed. Install it, or point Caasi at the renamed upstream with `caasi config set catalog.cosmos.cli.binaries [...]`.
exit code: 1
Once a CLI resolves, the arguments are the command — backend is the binary's
basename and kind is cosmos (default run name cosmos):
shellcaasi cosmos run predict --checkpoint /models/cosmos_predict1.pt --dry-run
Dry run — nothing was launched:
command: /usr/local/bin/cosmos predict --checkpoint /models/cosmos_predict1.pt
caasi cosmos run predict --checkpoint /models/cosmos_predict1.pt --name cosmos-predict
Started run 20260907-211737-cosmos-predict.
Follow it with: caasi logs 20260907-211737-cosmos-predict -f
caasi cosmos dataset
caasi cosmos dataset [--name NAME] [--dry-run] [--json] [ARGS…]
The same pass-through for Cosmos dataset work — kind: dataset, default run name
cosmos-dataset, and the same two honest failures:
shellcaasi cosmos dataset
Error: Nothing to forward — pass the arguments for the Cosmos CLI, e.g. `caasi cosmos dataset <args>`.
exit code: 1
caasi cosmos dataset prepare --input /data/raw --dry-run
Dry run — nothing was launched:
command: /usr/local/bin/cosmos prepare --input /data/raw
caasi scene reconstruct
Neural reconstruction is delegated, like everything else on this page: scene
reconstruct resolves the nurec capability of the usd catalog
domain (binary nurec) and hands it a capture — a ros2 bag directory
recorded by caasi scene capture, or any
dataset path. Caasi implements no reconstruction and reads no
frames; the run is tracked like any other (backend: nurec, kind:
reconstruct).
Usage
caasi scene reconstruct CAPTURE [--dry-run] [ARGS…]
| Parameter | Kind | Type | Default | Description |
|---|---|---|---|---|
CAPTURE | argument | path | required | Capture to reconstruct (ros2 bag directory or dataset path). |
--dry-run | option | flag | off | Show the command without starting a run. |
| trailing args | pass-through | Appended after the capture path, for the NuRec CLI to interpret. |
The two gates run in order — the capture must exist, then a reconstruction tool must resolve — and on a machine without NuRec this is the real output:
shellcaasi scene reconstruct /tmp/nope --dry-run
Error: Capture '/tmp/nope' not found.
exit code: 1
caasi scene reconstruct datasets/kitchen-capture --dry-run
Error: No neural reconstruction tool detected (nurec). Install NuRec, or point Caasi at its CLI: caasi config set catalog.usd.nurec.binaries "[<cli>]".
exit code: 1
With a CLI resolved — its own, or one you named with caasi config set
catalog.usd.nurec.binaries "[<cli>]" — the command is
[<nurec>, <capture>, ARGS…]:
shellcaasi scene reconstruct datasets/kitchen-capture --dry-run
Dry run — nothing was started:
command: /usr/local/bin/nurec datasets/kitchen-capture
caasi scene reconstruct datasets/kitchen-capture --output kitchen.usd
Reconstruction started for datasets/kitchen-capture.
Follow it with: caasi logs 20260907-213012-kitchen-capture -f
The run is named after the capture's directory name, and its manifest carries the capture path,
so caasi run list shows which capture produced which
reconstruction. Note that --output above is not a Caasi option: it is forwarded to the
NuRec CLI, which decides what it means.
caasi doctor --component platform
One doctor section — Foundation Models &
Teleop — covers GR00T, Cosmos, NuRec and the two teleop stacks. The GR00T
repo capability is the only core row here, so it is the only one that fails the check;
the packages, the CLIs and NuRec are optional and are skipped:
shellcaasi doctor --component platform
Environment Diagnostics
Foundation Models & Teleop
✗ GR00T repository — not found (GR00T_PATH, ~/Isaac-GR00T, ~/gr00t, ~/workspaces/Isaac-GR00T)
↳ Install it, or point Caasi at the renamed upstream with `caasi config set
catalog.groot.repo.env [...]`.
• gr00t package — not found (gr00t)
• Cosmos package — not found (cosmos_predict1, cosmos1)
• Cosmos CLI — not found (cosmos, ngc)
• NuRec (neural reconstruction) — not found (nurec)
✗ Keyboard teleop — not found (teleop_twist_keyboard)
↳ Install it, or point Caasi at the renamed upstream with `caasi config set
catalog.teleop.keyboard.packages [...]`.
• Joystick teleop — not found (teleop_twist_joy, joy)
✘ 2 issue(s) found, 0 warning(s). Run with --verbose for hints.
exit code: 1
caasi doctor --component platform --json | jq '[.checks[] | {name, status}]'
[ { "name": "GR00T repository", "status": "fail" },
{ "name": "gr00t package", "status": "skip" },
{ "name": "Cosmos package", "status": "skip" },
{ "name": "Cosmos CLI", "status": "skip" },
{ "name": "NuRec (neural reconstruction)", "status": "skip" },
{ "name": "Keyboard teleop", "status": "fail" },
{ "name": "Joystick teleop", "status": "skip" } ]
A resolved row reads ✓ NuRec (neural reconstruction) — /usr/local/bin/nurec and
carries the hint detected via binary (shown by --verbose). The two
teleop rows need the ros2 CLI: on a machine
without one they report • Keyboard teleop — skipped (ROS 2 CLI unavailable) with the
hint Install ROS 2 to enable Nav2 / MoveIt 2 / ros2_control checks. — they never fail
for a missing ROS 2.
No engine, no kernel, no model and no reconstruction is implemented by Caasi. What it adds is
detection (the catalog), a launcher choice, tracked runs with logs, and honest failures that name
the config key to fix. Every name on this page — engine keys, package names, binaries, script
paths — is catalog data: caasi config catalog physics,
caasi config catalog groot, caasi config catalog cosmos and
caasi config catalog usd print it.