Caasi v0.1.0 Advanced: native · shell

Native & Shell

The escape hatches. caasi native hands your arguments straight to the real tool (python.sh, isaaclab.sh, ros2) and mirrors its exit code, so Caasi never becomes the thing that blocks you. caasi shell drops you into a shell that already has the Isaac environment wired up. Both are foreground commands — they are not tracked runs.

When to use what

sim run / train / ros launch → background, tracked, logged. native / shell → foreground, exit code mirrored, nothing recorded. Use the escape hatch for one-off probing, odd flags Caasi does not model, and for wiring Caasi into CI where the exit code is the whole contract.

caasi native

caasi native sim [ARGS…]        # → <isaacsim>/python.sh   ARGS…
caasi native lab [ARGS…]        # → <isaaclab>/isaaclab.sh  ARGS…
caasi native ros [ARGS…]        # → <distro>/bin/ros2       ARGS…
caasi native run SCRIPT [--tool sim|lab|python] [ARGS…]
TargetResolved fromExecuted as
simtools.isaacsim registry, else ISAACSIM_PATH<path>/python.sh …
labtools.isaaclab registry, else ISAACLAB_PATH<path>/isaaclab.sh …
rosROS_DISTRO, else scan /opt/ros<distro>/bin/ros2 … (or ros2 on PATH)
run--tool (see below)an interpreter + your script

Resolution is the same one every other command uses — see Tool registry. The env var is only consulted as a fallback and only accepted if it points at an existing directory.

Execution semantics

Captured output ⇒ no live progress

Because stdout/stderr are captured and printed at the end, animated progress bars and interactive prompts do not render while the tool runs, and the tool sees pipes rather than a TTY. For interactive sessions use caasi shell — or call the tool directly.

caasi native sim

caasi native sim [ARGS…]

Raw Isaac Sim launcher. Useful for one-liners, for flags Caasi does not model, and for confirming that a registered install actually works.

shellcaasi native sim --version
5.1.0
caasi native sim -c "import omni.isaac.core; print('core ok')"
core ok
caasi native sim ~/work/standalone.py --headless --max_frames 200
[0.000s] Simulation App Starting...
...
[12.418s] app shutdown
exit code: 0  (mirrored from python.sh)

Nothing registered → error on stderr, exit 1:

shellcaasi native sim --version
Error: No install for isaacsim found; register one with 'caasi config set tools.isaacsim...'.
exit code: 1

Fix it once and every Caasi command benefits:

shellcaasi config set tools.isaacsim.path ~/.local/share/ov/pkg/isaac-sim-5.1.0
Set tools.isaacsim.path = /home/robot/.local/share/ov/pkg/isaac-sim-5.1.0
caasi native sim --version
5.1.0

caasi native lab

caasi native lab [ARGS…]

Raw Isaac Lab launcher (isaaclab.sh), so its own subcommands and flags are all available.

shellcaasi native lab --help
usage: isaaclab.sh [-h] {installconda,activateconda,...} ...
caasi native lab --install
[INFO] Installing Isaac Lab extensions...
caasi native lab -p source/standalone/workflows/rl_games/train.py --headless
... (this is exactly what 'caasi train' builds for backend lab) ...

Unregistered install → Error: No install for isaaclab found; register one with 'caasi config set tools.isaaclab...'. (exit 1).

caasi native ros

caasi native ros [ARGS…]

Raw ros2 CLI with the distro already located — no need to source setup.bash by hand. This is the fallback for any ROS verb that caasi ros does not wrap.

shellcaasi native ros topic list
/parameter_events
/rosout
/cmd_vel
caasi native ros pkg list | grep nav2_costmap
nav2_costmap_2d
caasi native ros service call /global_costmap/get_plan nav2_msgs/srv/GetPlan
requester: making request: ...
caasi native ros doctor --report
   All 5 checks passed

No distro → Error: ros2 CLI not found; source a ROS 2 distro first. (exit 1).

native ros vs. caasi ros

caasi ros list|topic|node|graph add uniformity, --json and tracked-run behaviour for long-lived things (ros launch, topic --echo). caasi native ros adds nothing but the resolved binary — take it when you want the real thing verbatim.

caasi native run

caasi native run SCRIPT [--tool sim|lab|python] [ARGS…]

Run your own script inside a chosen environment, without writing an experiment YAML.

--toolInterpreter usedCommand
python defaultthe Python running Caasi<sys.executable> SCRIPT ARGS…
simtools.isaacsim.python if set, else the launcher<python> SCRIPT ARGS… / <isaacsim>/python.sh SCRIPT ARGS…
labtools.isaaclab.python if set, else the launcher<python> SCRIPT ARGS… / <isaaclab>/isaaclab.sh -p SCRIPT ARGS…

Arguments after the script are forwarded untouched; --tool may appear before or after the script.

shellcaasi native run scripts/collect.py --tool sim --headless --count 50
collecting 50 episodes...
wrote /home/robot/datasets/demo/metadata.json
exit code: 0
caasi native run scripts/tune.py --tool lab --task Isaac-Velocity-Flat-G1-v0
[INFO] Task: Isaac-Velocity-Flat-G1-v0
caasi native run scripts/lint_local.py
all checks passed
# --tool python is the default: plain Python, no Isaac env
caasi native run scripts/report.py --tool nope
Error: Unknown --tool 'nope' (expected sim, lab or python).
exit code: 1

Registering an explicit interpreter avoids launcher overhead and is the recommended setup for script-heavy workflows:

shellcaasi config set tools.isaacsim.python /opt/isaac-sim/python.sh
Set tools.isaacsim.python = /opt/isaac-sim/python.sh
caasi native run scripts/collect.py --tool sim
# now runs as: /opt/isaac-sim/python.sh scripts/collect.py

Exit codes

CodeMeaning
0the underlying tool succeeded
1Caasi could not resolve a tool (Error: …), bad --tool, or the tool was killed by a signal
mirroredthe tool's own non-zero exit code (2, 3, 134, …) is returned as-is
2Caasi usage error, e.g. missing SCRIPT argument

That mirroring is what makes native commands safe in CI:

ci/run.sh#!/usr/bin/env bash
set -euo pipefail

caasi doctor || exit 1                      # environment gate
caasi native run tests/smoke.py --tool sim  # fails the build with the tool's own code
caasi sim run exps/ci.yaml && caasi run status latest --json | jq -e '.status == "succeeded"'

caasi shell

caasi shell [--command|-c TEXT] [--json]

Opens a bash session whose environment already knows about your Isaac installs — or runs a single command in that environment and returns.

What the environment contains

build_shell_env() starts from your current environment and, for each of isaacsim and isaaclab that resolves in the registry:

Tools that are not registered simply contribute nothing — the shell still opens.

It is an env injection, not an activation

caasi shell does not source setup.bash, setup_python_env.sh or activate a conda env, and it does not set up ROS. For ROS use caasi native ros … or the ros commands, which locate the distro themselves.

Interactive mode

Without --command, Caasi replaces its own process with bash (os.execvpe). You get a normal, fully interactive shell with a TTY — so editors, launchers with GUIs and progress bars all behave. Exiting the shell returns you to your original shell; there is nothing left of the Caasi process to return to.

shellcaasi shell
robot@ws:~/work$ echo "$ISAACSIM_PATH"
/home/robot/.local/share/ov/pkg/isaac-sim-5.1.0
robot@ws:~/work$ command -v python.sh
/home/robot/.local/share/ov/pkg/isaac-sim-5.1.0/bin/python.sh
robot@ws:~/work$ exit
# back in your original shell — no caasi process involved

--command: one-shot mode

Runs bash -c TEXT inside that environment (no timeout), prints stdout then stderr, and exits with the command's exit code (negative → 1). With --json you get the whole result as one object and the exit code is still mirrored:

{ "returncode": 0, "stdout": "…", "stderr": "…" }
shellcaasi shell -c 'echo "$ISAACSIM_PATH"; echo "$ISAACLAB_PATH"'
/opt/isaac-sim
/opt/isaaclab
caasi shell -c './python.sh -c "import omni.kit.app; print(1)"'
1
caasi shell -c 'false'
exit code: 1
caasi shell -c 'python -c "import torch; print(torch.__version__, torch.cuda.is_available())"' --json
{ "returncode": 0, "stdout": "2.7.0+cu128 true\n", "stderr": "" }
caasi shell -c 'ls /nope' --json
{ "returncode": 2, "stdout": "", "stderr": "ls: cannot access '/nope': No such file or directory\n" }
exit code: 2

One-shot mode is the natural fit for scripting and CI, because the exit code propagates:

shellcaasi shell -c 'cd "$ISAACLAB_PATH" && ./isaaclab.sh -p scripts/list_tasks.py' | head -5
Isaac-Velocity-Flat-G1-v0
Isaac-Navigation-Flat-G1-v0
...
caasi --quiet shell -c 'echo hidden'
# --quiet suppresses the re-printed output; the exit code still propagates
--quiet swallows child output

Both native and shell --command re-print captured output through Caasi's printer, which honours the global --quiet. Use --json (always printed, even under --quiet) when a script needs the text.

Options

OptionDefaultEffect
--command, -cnonerun this text via bash -c instead of opening a shell; exit code mirrored
--jsonfalseone-shot mode only: print {returncode, stdout, stderr}

native vs. shell vs. tracked runs

caasi native …caasi shellcaasi sim run / train / ros launch
Runs inforegroundforeground (or replaces the process)background, detached
Environmentexactly the tool's own launcherISAACSIM_PATH/ISAACLAB_PATH + bin on PATHlauncher env + your env: block + CAASI_* vars
Recordednonoyes — run dir with manifest, run.sh, logs
Exit codemirrored from the toolmirrored (one-shot) / bash's (interactive)the launch's; the run's outcome is checked later
Best forverbatim tool invocations, CI gatesexploring, multi-step manual workanything long, repeatable or worth keeping