> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cerulion.com/llms.txt
> Use this file to discover all available pages before exploring further.

# CLI reference

> Complete reference for every cerulion command, subcommand, flag, and argument.

The `cerulion` binary groups all functionality under top-level commands: `workspace`, `node`, `graph`, `topic`, `schema`, `tui`, `trace`, and `clean`.

Synopsis notation uses `<required>`, `[optional]`, `{a|b}` (choice), and `...` (repeatable). Synopsis lines are not directly runnable; each command includes a separate runnable example.

## Global

```text theme={null}
cerulion [--verbose] <command> [args...]
```

| Flag    | Long        | Type | Default | Meaning                                                                                    |
| ------- | ----------- | ---- | ------- | ------------------------------------------------------------------------------------------ |
| verbose | `--verbose` | bool | false   | Enable debug-level logging. Long form only; there is no `-v`. Applies to every subcommand. |

On error, `cerulion` prints `Error: <msg>` to stderr and exits with a failure code.

Most commands require a workspace, discovered by walking upward for a `Cargo.toml` containing `[workspace]` plus a `graphs/` directory. `workspace create`/`init`, `tui`, `trace`, and `clean` do not require discovery. `topic *` uses iceoryx2 discovery and needs no workspace.

## workspace

<AccordionGroup>
  <Accordion title="cerulion workspace create" icon="folder-plus" defaultOpen>
    Create a new workspace directory.

    ```text theme={null}
    cerulion workspace create <name>
    ```

    | Arg / flag        | Value name | Type   | Default | Meaning                                                 |
    | ----------------- | ---------- | ------ | ------- | ------------------------------------------------------- |
    | name (positional) | `<name>`   | String |         | Required. Workspace directory to create at `./<name>/`. |

    Creates `./<name>/` with `graphs/`, `nodes/`, `schemas/`, `Cargo.toml` (`[workspace]`, `members=["nodes/*"]`, `resolver="2"`, workspace dependencies for `cerulion_core` and `native_ros2_messages`), and `.cargo/config.toml`. Errors if `./<name>` already exists. Prints `Created workspace at <path>`.

    ```bash theme={null}
    cerulion workspace create my_robot
    ```
  </Accordion>

  <Accordion title="cerulion workspace init" icon="folder-gear">
    Initialize a workspace in place.

    ```text theme={null}
    cerulion workspace init [location]
    ```

    | Arg / flag            | Value name   | Type   | Default | Meaning                                                               |
    | --------------------- | ------------ | ------ | ------- | --------------------------------------------------------------------- |
    | location (positional) | `[location]` | String | `.`     | Directory to initialize in place (defaults to the current directory). |

    Initializes a workspace at `location`. Errors if a `Cargo.toml` with `[workspace]` already exists there. The workspace name is the directory's file name (fallback `cerulion_ws`). Prints `Initialized workspace at <path>`.

    ```bash theme={null}
    cerulion workspace init .
    ```
  </Accordion>
</AccordionGroup>

## node

Subcommands: `create`, `delete`, `modify`, `build`, `stage`, `run`, `list`, `info`. All require workspace discovery.

<AccordionGroup>
  <Accordion title="cerulion node create" icon="square-plus" defaultOpen>
    Create a node type.

    ```text theme={null}
    cerulion node create <node_type> [-o SCHEMA NAME] [-i SCHEMA NAME] [-T SCHEMA NAME] [--policy SPEC] [--raw-ffi]
    ```

    | Flag          | Short/Long               | Value names   | Type     | Default            | Meaning                                                                                                                                                      |
    | ------------- | ------------------------ | ------------- | -------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
    | node type     | (positional)             | `<node_type>` | String   |                    | Required. Becomes folder `nodes/<node_type>/` and (PascalCased) the struct name. Validated: non-empty, alphanumeric/underscore, must not start with a digit. |
    | output port   | `-o` / `--output`        | `SCHEMA NAME` | 2 values |                    | Add one output port. Both SCHEMA and NAME required. At most one `-o` per `create`.                                                                           |
    | input port    | `-i` / `--input`         | `SCHEMA NAME` | 2 values |                    | Add one regular input. Both required. At most one `-i` per `create`.                                                                                         |
    | trigger input | `-T` / `--trigger-input` | `SCHEMA NAME` | 2 values |                    | Add a trigger input → field emitted as `#[input(trigger)]`, policy set to `data_trigger=<NAME>`. Both required. At most one `-T` per node.                   |
    | policy        | `--policy`               | `SPEC`        | String   | (defaulting rules) | Trigger policy. See [Trigger policies](/cerulion/reference/trigger-policies).                                                                                |
    | raw FFI       | `--raw-ffi`              |               | bool     | false              | Generate the raw `extern "C"` FFI template instead of the `#[cerulion_node]` macro template.                                                                 |

    Schema is accepted in both `sensor_msgs/Image` (slash, canonical) and `sensor_msgs::Image` (colon) forms; canonicalized to slash. Output prints `Created node type '<node_type>'`.

    Generated files: `nodes/<type>/Cargo.toml` (cdylib, `cdylib` feature default) and `nodes/<type>/src/lib.rs` (macro or raw-FFI). Nothing is added to the workspace `Cargo.toml` if it already uses the `"nodes/*"` glob (the default).

    Validation errors (clean messages, no panic): passing a flag twice; `-T` name colliding with `-i` name; `--policy data_trigger=NAME` not matching a declared input; a source-only node (no `-i`/`-T`) without an explicit non-data `--policy`.

    ```bash theme={null}
    cerulion node create detector -T sensor_msgs/Image image -o geometry_msgs/PoseArray detections
    ```
  </Accordion>

  <Accordion title="cerulion node delete" icon="square-minus">
    Delete a node type.

    ```text theme={null}
    cerulion node delete <node_type>
    ```

    | Arg                    | Value name    | Type   | Meaning                        |
    | ---------------------- | ------------- | ------ | ------------------------------ |
    | node type (positional) | `<node_type>` | String | Required. Node type to delete. |

    Removes `nodes/<node_type>/` (recursive) and the workspace member entry. Errors `NodeNotFound` if absent. Prints `Deleted node type '<node_type>'`.

    ```bash theme={null}
    cerulion node delete detector
    ```
  </Accordion>

  <Accordion title="cerulion node modify" icon="pen-to-square">
    Modify an existing node type in place.

    ```text theme={null}
    cerulion node modify <node_type> [-i SCHEMA NAME] [-T SCHEMA NAME] [-o SCHEMA NAME] [--policy SPEC]
    ```

    | Flag          | Short/Long               | Value names   | Notes                                                                                                                                              |
    | ------------- | ------------------------ | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
    | node type     | (positional)             | `<node_type>` | Required. Node type to modify.                                                                                                                     |
    | input port    | `-i` / `--input`         | `SCHEMA NAME` | Add a regular input. At most one per call.                                                                                                         |
    | trigger input | `-T` / `--trigger-input` | `SCHEMA NAME` | Add a trigger input (`#[input(trigger)]`) and set policy `data_trigger=<NAME>`, clearing conflicting node-level policy args. At most one per call. |
    | output port   | `-o` / `--output`        | `SCHEMA NAME` | Add an output. At most one per call.                                                                                                               |
    | policy        | `--policy`               | `SPEC`        | Set/replace the trigger policy. `data_trigger=NAME` requires NAME to be an existing input or one added in the same call.                           |

    Mutates the node's `src/lib.rs` in place (preserves the tick body, comments, and other fields). `-T` and `--policy data_trigger=NAME` are equivalent; supplying both requires they agree. Prints per-action lines, e.g. `Added input 'image' to 'detector' as the data trigger`, `Set policy=period_ms=33 on 'detector'`, `Promoted existing input 'x' to data trigger on 'detector'`.

    <Note>
      The only user surface for setting external triggering is `--policy external`.
    </Note>

    ```bash theme={null}
    cerulion node modify detector -i sensor_msgs/Imu imu --policy period_ms=33
    ```
  </Accordion>

  <Accordion title="cerulion node build" icon="hammer">
    Build a node crate.

    ```text theme={null}
    cerulion node build <node_type> [--release]
    ```

    | Flag      | Long         | Type          | Default | Meaning                       |
    | --------- | ------------ | ------------- | ------- | ----------------------------- |
    | node type | (positional) | `<node_type>` |         | Required. Node type to build. |
    | release   | `--release`  | bool          | false   | Build in release mode.        |

    Runs `cargo build -p <node_type>` (adds `--release` if set) in the workspace root. Errors `BuildFailed` (with cargo stderr) on failure. Prints `Built '<node_type>'`.

    <Warning>
      Requires `cargo` on PATH; the CLI shells out to it.
    </Warning>

    ```bash theme={null}
    cerulion node build detector --release
    ```
  </Accordion>

  <Accordion title="cerulion node stage" icon="layer-group">
    Append a node instance to a graph YAML file.

    ```text theme={null}
    cerulion node stage <node_type> [-i ID] [-g GRAPH] [-p PREFIX] [-I NAME SOURCE]...
    ```

    | Flag          | Short/Long        | Value names   | Type                 | Default    | Meaning                                                                                                          |
    | ------------- | ----------------- | ------------- | -------------------- | ---------- | ---------------------------------------------------------------------------------------------------------------- |
    | node type     | (positional)      | `<node_type>` | String               |            | Required. Node type to stage.                                                                                    |
    | id            | `-i` / `--id`     |               | Option\<String>      | node\_type | Node instance ID (defaults to the node type).                                                                    |
    | graph         | `-g` / `--graph`  |               | Option\<String>      | auto       | Target graph. If omitted: auto-selects the sole graph; errors if 0 or more than 1 exist.                         |
    | prefix        | `-p` / `--prefix` |               | Option\<String>      |            | Accepted for forward compatibility; topic prefix resolution lives on the graph, so this flag has no effect here. |
    | input binding | `-I`              | `NAME SOURCE` | 2 values, repeatable |            | Wire input `NAME` to `SOURCE`. `[node,port]` form → `node/port`; `node/port` passes through.                     |

    Outputs (with schemas) are auto-derived from the node's source metadata. A duplicate node ID is an error. The modified graph is validated. Prints `Staged '<type>' into graph '<graph>'`.

    ```bash theme={null}
    cerulion node stage detector -g perception -I image [camera,image]
    ```
  </Accordion>

  <Accordion title="cerulion node run" icon="play">
    Smoke-run a single node.

    ```text theme={null}
    cerulion node run <node_type> [-p PREFIX] [-i ID] [--release] [--no-cpu-dma-lock] [--no-monitor-wait]
    ```

    | Flag            | Short/Long          | Type            | Default      | Meaning                                                                                                                                                                                                                                                                                                                             |
    | --------------- | ------------------- | --------------- | ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | node type       | (positional)        | String          |              | Required. Node type to run.                                                                                                                                                                                                                                                                                                         |
    | prefix          | `-p` / `--prefix`   | Option\<String> | `standalone` | Topic prefix.                                                                                                                                                                                                                                                                                                                       |
    | id              | `-i` / `--id`       | Option\<String> | node\_type   | Instance ID.                                                                                                                                                                                                                                                                                                                        |
    | release         | `--release`         | bool            | false        | Force the release-profile cdylib (`target/release`). Without this flag the freshest built cdylib between `target/debug` and `target/release` is auto-selected by modification time — the profile you most recently built wins.                                                                                                      |
    | no-cpu-dma-lock | `--no-cpu-dma-lock` | bool            | false        | Disable the automatic CPU C-state cap (Linux only). Pass this on laptops or power-sensitive dev boxes. See `graph run` for environment variable overrides.                                                                                                                                                                          |
    | no-monitor-wait | `--no-monitor-wait` | bool            | false        | Opt out of the live-loop CPU park (Linux only). By default on Linux x86\_64 and Linux aarch64 in live mode, Cerulion uses a per-core CPU park to reduce idle wake latency; when the park is active, the graph-derived auto C-state cap is not applied. Pass this to disable it. See `graph run` for environment variable overrides. |

    Creates a hidden temp graph `__temp_<type>`, stages the node, runs it in live mode (validation skipped), and deletes the temp graph YAML on exit. Ctrl+C stops it.

    ```bash theme={null}
    cerulion node run detector -p standalone
    ```
  </Accordion>

  <Accordion title="cerulion node list" icon="list">
    List node types.

    ```text theme={null}
    cerulion node list
    ```

    No arguments. Prints a table with columns `TYPE  INPUTS  OUTPUTS  POLICY` (counts plus a short policy label). Empty workspace prints `No nodes found.`

    ```bash theme={null}
    cerulion node list
    ```
  </Accordion>

  <Accordion title="cerulion node info" icon="circle-info">
    Show details for a node type.

    ```text theme={null}
    cerulion node info <node_type>
    ```

    | Arg                    | Value name    | Type   | Meaning                         |
    | ---------------------- | ------------- | ------ | ------------------------------- |
    | node type (positional) | `<node_type>` | String | Required. Node type to inspect. |

    Prints `Node type`, `Policy`, and `Inputs:`/`Outputs:` (name plus schema or `(untyped)`). Metadata is parsed from `src/lib.rs`; the source is the single source of truth.

    Policy short labels: `period <N>ms`, `deadline <N>ms`, `sync <N>ms`, `sync ∞` (unbounded), `external`, `trigger:<input>`, `-` (none).

    ```bash theme={null}
    cerulion node info detector
    ```
  </Accordion>
</AccordionGroup>

## graph

Subcommands: `create`, `run`, `validate`, `list`.

<AccordionGroup>
  <Accordion title="cerulion graph create" icon="diagram-project" defaultOpen>
    Create a graph file.

    ```text theme={null}
    cerulion graph create <name> [-n PREFIX]
    ```

    | Flag   | Short/Long        | Type            | Default | Meaning                                                                                                                             |
    | ------ | ----------------- | --------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------- |
    | name   | (positional)      | String          |         | Required. Graph name → `graphs/<name>.yaml`.                                                                                        |
    | prefix | `-n` / `--prefix` | Option\<String> |         | Topic prefix. If omitted, the `prefix:` line is omitted from the file and resolved to the hostname (without `.local`) at load time. |

    Creates `graphs/<name>.yaml`. Errors if the graph already exists. Prints `Created graph '<name>'`.

    ```bash theme={null}
    cerulion graph create perception -n robot1
    ```
  </Accordion>

  <Accordion title="cerulion graph run" icon="play">
    Run a graph.

    ```text theme={null}
    cerulion graph run <name> [--time-source CLOCK] [--no-validate] [--release] [--no-cpu-dma-lock] [--no-monitor-wait]
    ```

    | Flag            | Form                                    | Default | Meaning                                                                                                                                                                                                                                                                                                                        |
    | --------------- | --------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
    | name            | (positional)                            |         | Required. Graph to run.                                                                                                                                                                                                                                                                                                        |
    | time-source     | `--time-source real\|virtual\|external` | `real`  | Clock mode. `real`: live event-driven loop — wakes on each incoming message. `virtual`: deterministic 1 ms step loop for replay and benchmarking. `external`: accepted but not yet functional.                                                                                                                                 |
    | no validate     | `--no-validate`                         | off     | Skip pre-run workspace validation.                                                                                                                                                                                                                                                                                             |
    | release         | `--release`                             | off     | Force release-profile cdylibs (`target/release`). Without this flag the freshest built cdylib between `target/debug` and `target/release` is auto-selected by modification time — the profile you most recently built wins. The pre-run validation uses the same mode.                                                         |
    | no-cpu-dma-lock | `--no-cpu-dma-lock`                     | off     | Disable the automatic CPU C-state cap (Linux only). No effect under `--time-source virtual`. Pass this on laptops or power-sensitive dev boxes.                                                                                                                                                                                |
    | no-monitor-wait | `--no-monitor-wait`                     | off     | Opt out of the live-loop CPU park (Linux only). By default on Linux x86\_64 and Linux aarch64 in live mode, Cerulion uses a per-core CPU park to reduce idle wake latency. When the park is active, the graph-derived auto C-state cap is not applied. Pass this to disable the park. No effect under `--time-source virtual`. |

    Loads cdylibs, builds the runtime, and runs the graph until Ctrl+C or a node requests shutdown. In the default live mode (`--time-source real`) the graph wakes and processes messages as they arrive. Validation failures only warn and continue; they do not block `run`.

    In live mode, Cerulion automatically applies a CPU C-state cap for timing-sensitive graphs to reduce wake latency (Linux only; best-effort — warns on failure if the cap cannot be acquired). Pass `--no-cpu-dma-lock` to disable it. Environment variable overrides: `CERULION_CPU_DMA_LOCK=1` forces a full C0 pin; `CERULION_CPU_DMA_LOCK=0` disables the cap; `CERULION_CPU_DMA_LOCK_US=N` sets an explicit N-µs cap. The `--no-cpu-dma-lock` flag takes precedence over all env vars.

    On Linux x86\_64 and Linux aarch64 in live mode, Cerulion uses a per-core CPU park to reduce idle wake latency. When the park is active, the graph-derived auto C-state cap is not applied (an explicit `CERULION_CPU_DMA_LOCK=1` or `CERULION_CPU_DMA_LOCK_US=N` override still takes effect). To opt out of the park entirely, pass `--no-monitor-wait`. Environment variable overrides (only honored when `--no-monitor-wait` is absent): `CERULION_MONITOR_WAIT=1` force-enables the park; `CERULION_MONITOR_WAIT=0` disables it; any other non-empty value warns and uses the auto default. `CERULION_DOORBELL=1` enables waking on incoming data as well as on the timer deadline; `CERULION_DOORBELL=0` restricts to timer-only wakes; any other non-empty value warns and uses the auto default.

    `CERULION_FIRE_THREADS=N` sets the number of threads used for within-level parallel node execution (must be a positive integer; if unset or invalid, auto-sizes to `min(available_parallelism, max_level_width)`; read once at graph build). `CERULION_LIVE_SPIN_US=N` controls how long (µs) the live loop busy-waits for an incoming message before yielding the core (`--time-source real`/`external` only; no effect with `virtual`). `=0` disables busy-waiting; `=N` (N > 0) caps it at N µs (max 100,000; larger values are clamped with a warning). When unset, the duration is auto-sized to the graph's timing requirements — a tight-period graph polls briefly, a quiescent graph yields immediately. `graph run` also runs an iceoryx2 dead-node cleanup at start.

    <Warning>
      `run` loads compiled cdylibs from the cargo target directory. The default is `target/{debug,release}/` in the workspace root. If `CARGO_TARGET_DIR` is set in your shell, both `cerulion node build` and `cerulion graph run` use it, so a shared or custom target directory works without any extra flags.
    </Warning>

    ```bash theme={null}
    # Default: live mode
    cerulion graph run perception

    # Deterministic mode (replay / benchmarking)
    cerulion graph run perception --time-source virtual
    ```
  </Accordion>

  <Accordion title="cerulion graph validate" icon="circle-check">
    Validate a graph.

    ```text theme={null}
    cerulion graph validate <name> [--release]
    ```

    | Flag    | Form         | Type   | Default | Meaning                                                                                                                                                                                                                                                  |
    | ------- | ------------ | ------ | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | name    | (positional) | String |         | Required. Graph to validate.                                                                                                                                                                                                                             |
    | release | `--release`  | bool   | false   | Force release-profile cdylibs (`target/release`) when resolving node libraries. Without this flag the freshest built cdylib between `target/debug` and `target/release` is auto-selected by modification time. The report shows which profile was found. |

    Runs the validation report (topology, node crate exists, ports parse, cdylib exists, input bindings and schema match, data\_trigger bindings). Prints the report and exits non-zero if any check fails.

    ```bash theme={null}
    cerulion graph validate perception
    ```
  </Accordion>

  <Accordion title="cerulion graph list" icon="list">
    List graphs.

    ```text theme={null}
    cerulion graph list
    ```

    No arguments. Lists graph names (file stems of `*.yaml`), sorted. Empty prints `No graphs found.`

    ```bash theme={null}
    cerulion graph list
    ```
  </Accordion>
</AccordionGroup>

## topic

Uses iceoryx2 service discovery: enumerates services ending in `/data` (Cerulion creates `{topic}/data` and `{topic}/event` per topic). No workspace required.

<AccordionGroup>
  <Accordion title="cerulion topic list" icon="list" defaultOpen>
    List active topics.

    ```text theme={null}
    cerulion topic list
    ```

    Lists active topic names (sorted). Header `TOPIC`. Empty prints `No active topics.`

    ```bash theme={null}
    cerulion topic list
    ```
  </Accordion>

  <Accordion title="cerulion topic info" icon="circle-info">
    Show topic info.

    ```text theme={null}
    cerulion topic info <topic>
    ```

    | Arg                | Value name | Type   | Meaning                     |
    | ------------------ | ---------- | ------ | --------------------------- |
    | topic (positional) | `<topic>`  | String | Required. Topic to inspect. |

    Prints the topic info string.

    ```bash theme={null}
    cerulion topic info robot1/camera/image
    ```
  </Accordion>

  <Accordion title="cerulion topic echo" icon="terminal">
    Print messages from a topic.

    ```text theme={null}
    cerulion topic echo <topic>
    ```

    | Arg                | Value name | Type   | Meaning                          |
    | ------------------ | ---------- | ------ | -------------------------------- |
    | topic (positional) | `<topic>`  | String | Required. Topic to subscribe to. |

    Subscribes and prints messages until Ctrl+C. Pretty-prints `std_msgs/String` and `sensor_msgs/Image` (by FNV-1a schema hash); hex preview otherwise.

    ```bash theme={null}
    cerulion topic echo robot1/camera/image
    ```
  </Accordion>

  <Accordion title="cerulion topic hz" icon="gauge">
    Measure publish rate.

    ```text theme={null}
    cerulion topic hz <topic>
    ```

    | Arg                | Value name | Type   | Meaning                     |
    | ------------------ | ---------- | ------ | --------------------------- |
    | topic (positional) | `<topic>`  | String | Required. Topic to measure. |

    Measures the publish rate until Ctrl+C.

    ```bash theme={null}
    cerulion topic hz robot1/camera/image
    ```
  </Accordion>
</AccordionGroup>

## schema

Subcommands: `create`, `delete`, `info`.

<AccordionGroup>
  <Accordion title="cerulion schema create" icon="file-plus" defaultOpen>
    Create a schema file.

    ```text theme={null}
    cerulion schema create <name>
    ```

    | Arg               | Value name | Type   | Meaning                                              |
    | ----------------- | ---------- | ------ | ---------------------------------------------------- |
    | name (positional) | `<name>`   | String | Required. Schema name → `schemas/<PascalName>.yaml`. |

    Creates `schemas/<PascalName>.yaml` with a `schemas:` skeleton (description plus a `fields:` comment). Errors if the schema exists. Prints `Created schema '<name>'`.

    ```bash theme={null}
    cerulion schema create Reading
    ```
  </Accordion>

  <Accordion title="cerulion schema delete" icon="file-minus">
    Delete a schema file.

    ```text theme={null}
    cerulion schema delete <name>
    ```

    | Arg               | Value name | Type   | Meaning                     |
    | ----------------- | ---------- | ------ | --------------------------- |
    | name (positional) | `<name>`   | String | Required. Schema to delete. |

    Removes `schemas/<name>.yaml`. Errors `SchemaNotFound`. Prints `Deleted schema '<name>'`.

    ```bash theme={null}
    cerulion schema delete Reading
    ```
  </Accordion>

  <Accordion title="cerulion schema info" icon="circle-info">
    Show schema details.

    ```text theme={null}
    cerulion schema info <name>
    ```

    | Arg               | Value name | Type   | Meaning                                                                        |
    | ----------------- | ---------- | ------ | ------------------------------------------------------------------------------ |
    | name (positional) | `<name>`   | String | Required. Schema name. Accepts qualified ROS2 names like `sensor_msgs::Image`. |

    First tries a ROS2 `.msg` lookup at `../native_ros2_messages/msg/<pkg>/<Type>.msg` (for qualified names); prints fields, Rust types, and min wire size. Falls back to a workspace YAML schema (prints `Schema`, `Description`, `Fields`, `Hash: 0x...`).

    ```bash theme={null}
    cerulion schema info sensor_msgs::Image
    ```
  </Accordion>
</AccordionGroup>

## tui

```text theme={null}
cerulion tui
```

Launches the interactive ratatui dashboard. Logging is suppressed in TUI mode.

```bash theme={null}
cerulion tui
```

## trace inspect

```text theme={null}
cerulion trace inspect <dir> [-t TOPIC] [-n N] [-r]
```

| Flag    | Short/Long         | Value name | Type            | Default | Meaning                                           |
| ------- | ------------------ | ---------- | --------------- | ------- | ------------------------------------------------- |
| dir     | (positional)       | `<dir>`    | String          |         | Required. Directory of `trace_*.jsonl` bag files. |
| filter  | `-t` / `--filter`  | `TOPIC`    | Option\<String> |         | Filter by exact topic.                            |
| limit   | `-n` / `--limit`   | `N`        | Option\<usize>  |         | Limit the number of records.                      |
| reverse | `-r` / `--reverse` |            | bool            | false   | Reverse order (most-recent first).                |

Reads `trace_*.jsonl` bag files (lexicographic order) and prints `<topic> seq=<N> t=<ts>ns schema=0x<HASH>` per record.

```bash theme={null}
cerulion trace inspect ./traces -t robot1/camera/image -n 100 -r
```

## clean

```text theme={null}
cerulion clean
```

Removes iceoryx2 on-disk bookkeeping for dead nodes only (live sibling processes are untouched). Prints cleanup counts plus per-cause remediation.

```bash theme={null}
cerulion clean
```
