Configuration
Caasi is configured with layered YAML files. There is no database, no daemon and nothing hidden:
caasi config show always prints exactly what the CLI will use, and every command reads
the same merged result.
Config files & precedence
Four file locations are merged, lowest precedence first:
| # | Source | Location | Purpose |
|---|---|---|---|
| 1 | Built-in defaults | compiled into Caasi | Sane starting point (see below). |
| 2 | Global config | ~/.config/caasi/config.yaml(or $XDG_CONFIG_HOME/caasi/config.yaml) | Your machine: tool registry, paths, remotes. |
| 3 | Project config | ./caasi.yaml (current directory) | Per-project overrides. Inside a project this is also the project marker file — see Projects. |
| 4 | CAASI_CONFIG | any path from the env var | CI / experiment-specific config. |
| 5 | --config <path> | any path from the flag | Highest precedence, one-shot override. |
Merging is a recursive dict merge: a project file that sets one key under
tools: does not wipe the rest of the global registry. After merging, the
CAASI_LANG, CAASI_LAYOUT and CAASI_HELP_ORDER environment
variables (if set) override language, layout and help_order.
A config file that is unreadable, invalid YAML, or whose top level is not a mapping is
silently treated as empty. If your settings seem ignored, run caasi config path
and caasi config show.
Built-in defaults
language: en
layout: rich # 'rich' (bordered tables) or 'plain' (aligned columns)
help_order: grouped # 'grouped' (titled panels), 'core' or 'alpha' (flat a–z)
defaults:
output: table
paths:
runs: ~/.caasi/runs # where tracked runs live
datasets: ~/.caasi/datasets # where generated datasets go
tools: {} # the tool registry (see below)
A complete global config example
# ~/.config/caasi/config.yaml
language: en
paths:
runs: /data/caasi-runs # big disk for logs and artifacts
tools:
isaacsim:
default: "6.0"
versions:
"6.0": { path: /opt/isaac-sim-6.0 }
"5.1": { path: /opt/isaac-sim-5.1 }
isaaclab:
versions:
"2.0": { path: /opt/IsaacLab, python: /opt/IsaacLab/_isaac_sim/python.sh }
remotes:
gpu-box:
host: 10.0.0.5
user: robot
port: 2222
identity: ~/.ssh/id_ed25519
path: ~/experiments # remote working directory
The tool registry
The registry is how you tell Caasi where your installs are — and which version to use
when you have several side by side (very common with Isaac Sim). It lives under the top-level
tools: key.
Multi-version form
tools:
isaacsim:
default: "6.0" # which version commands resolve to
versions:
"6.0": { path: /opt/isaac-sim-6.0 }
"5.1": { path: /opt/isaac-sim-5.1, python: /opt/isaac-sim-5.1/python.sh }
Single-install form
tools:
isaaclab:
path: /opt/IsaacLab
python: /opt/IsaacLab/_isaac_sim/python.sh # optional interpreter override
How a tool is resolved
- With the multi-version form, the requested version is used; without one,
default; without a default, the first version key in file order. - Version keys are compared as strings, so a float
6.0default matches the key"6.0". Quoting version keys in YAML is recommended. - Resolution produces
{name, version, path, python}; commands then derive their launchers frompath: Isaac Sim →<path>/python.sh, Isaac Lab →<path>/isaaclab.sh(unlesspythonis set).
Set registry entries with dotted keys (quote version segments):
shellcaasi config set tools.isaacsim.versions."6.0".path /opt/isaac-sim-6.0
Set tools.isaacsim.versions."6.0".path = /opt/isaac-sim-6.0 (saved to /home/you/.config/caasi/config.yaml)
caasi config set tools.isaacsim.default "6.0"
caasi config tools
Tool Default Versions Resolved path
isaacsim 6.0 6.0 /opt/isaac-sim-6.0
Registry vs. environment variables
If a tool is not in the registry, Caasi falls back to detection
(ISAACSIM_PATH/ISAACLAB_PATH env vars, common install locations, pip
metadata — see Architecture). The registry always wins when
present, and is the only way to manage multiple versions.
Capability catalog
Caasi is a layer over tools it does not own, so no upstream package name, binary or launch file
is hardcoded in the CLI. They are rows in a capability catalog:
domains (isaacros, slam, motion,
physics, teleop, sdg, …) hold capabilities
(slam.visual, physics.gazebo, …), and every capability lists the
probes that can find it on this machine. The catalog is overridable from config under the
top-level catalog: key, so an upstream rename is a config edit rather than a Caasi
release. Print the effective table with
caasi config catalog.
Probe order
Probing is subprocess, pip-metadata and filesystem only — the CLI never imports the ecosystem it detects. A capability's fields are tried in this order and the first hit wins:
| # | Field | Probe | Reported as |
|---|---|---|---|
| 1 | packages | ros2 pkg prefix <name> (skipped entirely when there is no ros2 CLI) | package → the install prefix |
| 2 | binaries | <name> found on PATH | binary → the executable path |
| 3 | modules | pip metadata of the first listed distribution that exists (never imported) | module → its version |
| 4 | env | the variable is set and non-empty | env → its value |
| 5 | paths | glob under the capability's tool root; a pattern starting with ~ or / is globbed from its own parent directory instead | path → the first match in sorted order |
Two fields sit outside that chain. script is resolved on its own — an absolute path
is used when the file exists, a relative one is joined to the tool root — and is attached to the
result whether or not the capability was found. launch is a
[package, file] pair handed to ros2 launch. The tool root itself comes
from the tool registry first and from the tool's environment variable
(ISAACSIM_PATH, ISAACLAB_PATH, GR00T_PATH) second.
Overriding a capability
The override path is catalog.<domain>.<capability>.<field>, and
the rule is deliberately the only one: an override replaces that field wholesale —
lists are not appended to. An override may also add a capability, or a whole domain, that the
built-ins do not know about. default is reserved at domain level: it names the
capability a group uses when you omit --backend.
catalog:
slam:
default: toolbox # used when `caasi slam launch` gets no --backend
visual:
label: "Visual SLAM (v4)" # row label in status / doctor output
packages: [isaac_ros_visual_slam_v4]
launch: [isaac_ros_visual_slam_v4, visual_slam.launch.py]
topics: [/tf, /map]
group: slam # the caasi group that wraps it
core: true # absent = a doctor failure, not a skip
physics:
newton:
paths: [isaac-sim.newton.sh] # relative to the domain's tool root (isaacsim)
modules: [newton-physics, newton]
Overridable fields: label, packages, binaries,
modules, env, paths, topics (lists),
launch (a two-element pair), script, group,
tool and core. Unknown fields are ignored, and key comes
from the mapping key. A domain that ships a tool root (perception,
physics, groot, usd, data, teleop,
sdg) forces it on every capability it contains, so tool only takes effect
on domains that have none.
Every field is reachable through caasi config set — list values are parsed as
YAML: caasi config set catalog.slam.visual.packages "[isaac_ros_visual_slam_v4]".
See the version-churn firewall for the full walkthrough.
Physics engine keys
The physics domain doubles as the engine registry, and two keys outside
catalog: steer it (see caasi physics):
| Key | Default | Effect |
|---|---|---|
physics.default | physx | Engine used by physics run / physics benchmark when --engine is absent. It must be a capability key of the physics domain; anything else exits 1 with Error: Unknown physics engine '<key>'. Known: …. |
physics.engines.<key>.launcher | — | Script that replaces the experiment's own launcher for that engine. A relative value is resolved against the isaacsim tool root, and it is only used when the resulting file exists; otherwise a launcher the catalog found through paths that ends in .sh is used. |
physics:
default: gazebo
engines:
gazebo:
launcher: ~/bin/gz-run.sh
Whichever engine is applied, the run also receives
CAASI_PHYSICS_ENGINE=<key>. synth and teleop read no
keys of their own: synth generate resolves the sdg domain's
replicator capability, teleop start resolves
catalog.teleop.default and then keyboard → joy →
xr, and both write under paths.datasets — see
synth & teleop.
Remotes
The remotes: section defines SSH machines for the
remote commands:
remotes:
<name>:
host: 10.0.0.5 # required — entries without host are ignored
user: robot # optional
port: 2222 # optional
identity: ~/.ssh/id_ed25519 # optional, ~ is expanded
path: ~/experiments # optional remote working directory
Commands accept the exact name or any unique prefix (caasi remote run gpu nvidia-smi
matches gpu-box when unambiguous). Caasi only builds ssh command lines —
keys, agents and ~/.ssh/config are honored because the system ssh client
does the work.
caasi config
Inspect and edit the configuration from the command line.
caasi config show
caasi config show [--json]
Prints the merged effective configuration (human mode renders YAML; --json
emits the same object). This is the ground truth of what Caasi will do.
shellcaasi config show
language: en
layout: rich
help_order: grouped
defaults:
output: table
paths:
runs: ~/.caasi/runs
datasets: ~/.caasi/datasets
tools:
isaacsim:
default: '6.0'
versions:
'6.0':
path: /opt/isaac-sim-6.0
caasi config get
caasi config get KEY
Reads one dotted key. Dicts and lists are printed as YAML, scalars as plain text.
A missing (or null) key exits 1 with Error: Key '<key>' is not set.
shellcaasi config get paths.runs
~/.caasi/runs
caasi config get tools.isaacsim.versions
'6.0':
path: /opt/isaac-sim-6.0
caasi config set
caasi config set KEY VALUE
VALUEis parsed as YAML, sotrue,42and6.0become bool/number types; anything unparseable stays a string. Quote values you want to keep as strings (caasi config set tools.isaacsim.default '"6.0"').- Intermediate dicts along the dotted path are created automatically.
- The result is persisted to the global config file — and note that
setwrites the fully merged configuration there, so afterwards the global file contains everything (defaults + project + env overrides folded in).
caasi config path
caasi config path
Shows the four possible sources, which of them are active, and the effective merge order — the fastest way to debug “why is my setting ignored?”.
shellcaasi config path
✓ --config (not set)
✓ CAASI_CONFIG (not set)
✓ Global config file /home/you/.config/caasi/config.yaml
• Project config file ./caasi.yaml
Effective sources in merge order:
/home/you/.config/caasi/config.yaml
caasi config tools
caasi config tools [--json]
Lists every registered tool with its default version, all versions, and the resolved
{version, path, python} (or null when unresolvable). With no registry
entries it prints a usage hint. Always exits 0.
shellcaasi config tools --json | jq '.isaacsim.resolved'
{
"version": "6.0",
"path": "/opt/isaac-sim-6.0",
"python": null
}
caasi config catalog
caasi config catalog [DOMAIN] [--json]
Prints the effective capability catalog — the built-in domains merged with your
catalog: overrides — so you can see exactly which upstream names Caasi will probe.
Omit DOMAIN to print every domain; an unknown one exits 1 with
Error: Unknown catalog domain: <name>. Known domains: …. See
Capability catalog.
| Argument / option | Type | Default | Description |
|---|---|---|---|
DOMAIN | str | every domain | Catalog domain to show (omit to show every domain). |
--json | flag | off | Machine-readable output. |
shellcaasi config catalog slam
SLAM slam · ros
capability upstream targets launch file caasi group
visual isaac_ros_visual_slam isaac_ros_visual_slam visual_slam.launch.py —
toolbox slam_toolbox slam_toolbox online_async_launch.py —
cartographer cartographer_ros cartographer_ros cartographer.launch.py —
Every field is overridable: `caasi config set catalog.<domain>.<capability>.<field> <value>`
caasi config catalog nope
Error: Unknown catalog domain: nope. Known domains: isaacros, perception, slam, mapping, motion, nitros, physics, warp, groot, cosmos, usd, data, teleop, sdg
When the domain has a default, the heading carries it —
SLAM (default: toolbox) slam · ros. --json emits one object per domain,
or a single object when DOMAIN is given:
shellcaasi config catalog teleop --json
{
"key": "teleop",
"title": "catalog.domain.teleop",
"kind": "ros",
"verbs": ["start", "record", "stop", "replay"],
"tool": "isaacsim",
"capabilities": [
{
"key": "keyboard",
"label": "catalog.teleop.keyboard",
"packages": ["teleop_twist_keyboard"],
"binaries": [],
"modules": [],
"env": [],
"paths": [],
"launch": ["teleop_twist_keyboard", "teleop-launch.py"],
"script": null,
"topics": [],
"group": null,
"tool": "isaacsim",
"core": true
}
… one object per capability, in catalog order …
],
"default": null,
"overrides": {}
}
overrides is the raw catalog.<domain> mapping from your config,
so what you changed and what is built-in stays visible at a glance.
Environment variables
Consumed by Caasi
| Variable | Effect |
|---|---|
CAASI_CONFIG | Path to an extra config file (merged above global/project). |
CAASI_LANG | Overrides language after merging (e.g. en). |
CAASI_LAYOUT | Overrides layout after merging: rich (bordered tables) or plain (space-aligned columns). The --layout flag wins over both. |
CAASI_HELP_ORDER | Overrides help_order after merging: grouped (titled panels, default), core (entry points first, then a–z) or alpha (flat a–z). Applies to the root listing only; there is no flag, because --help exits before flags are stored. |
XDG_CONFIG_HOME | Relocates the global config dir ($XDG_CONFIG_HOME/caasi/config.yaml). |
ISAACSIM_PATH | Fallback Isaac Sim location when the registry has none. |
ISAACLAB_PATH | Fallback Isaac Lab location when the registry has none. |
ROS_DISTRO | Selects the ROS 2 distro (otherwise /opt/ros is scanned). |
RMW_IMPLEMENTATION | Reported by caasi ros status (not modified). |
ISAAC_ROS_WS | Isaac ROS workspace root, tried before the tools.isaacros registry entry and the common paths — see isaac-ros. |
GR00T_PATH | GR00T repository root: the catalog.groot.repo probe and the fallback for the tools.groot registry entry — see groot. |
AMENT_PREFIX_PATH | With COLCON_PREFIX_PATH and PYTHONPATH, proves the ROS 2 environment is already sourced. When none of them names the distro root, Caasi wraps ros2 commands in a shell that sources setup.bash first. |
ROS_DOMAIN_ID | Reported by caasi doctor -c accelerated (not modified). |
ROS_DISABLE_NITROS | Probed as the nitros.disable capability and reported by caasi doctor -c accelerated (not modified). |
Any capability can also be found through its own env field — see
Capability catalog.
Produced for child processes
Caasi sets these in the environment of everything it launches — your scripts can rely on them:
| Variable | Set by | Content |
|---|---|---|
CAASI_EXPERIMENT | sim run, train, benchmark start, dataset generate | Absolute path of the experiment YAML. |
ISAACSIM_PATH / ISAACLAB_PATH | sim run, train, … (sim/lab backends) | Resolved install path. |
CAASI_DATASET_DIR | dataset generate | Dataset directory the script should write into (also passed as --dataset-dir). |
CAASI_RUN_DIR | replay, view attach | Run directory for the viewer. |
CAASI_REPLAY_SPEED, CAASI_REPLAY_EPISODE | replay | Replay parameters exported to the viewer. |
CAASI_PHYSICS_ENGINE | physics run, physics benchmark | Key of the engine that was applied (physx, gazebo, …) — see Capability catalog. |
Feed a per-job config without touching the machine setup:
CAASI_CONFIG=ci/caasi-gpu.yaml caasi sim run exp.yaml, or
caasi --config ci/caasi-gpu.yaml sim run exp.yaml for highest precedence.