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
| Flag | Long | Type | Default | Meaning |
|---|---|---|---|---|
| verbose | --verbose | bool | false | Enable debug-level logging. Long form only; there is no -v. Applies to every subcommand. |
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
cerulion workspace create
cerulion workspace create
Create a new workspace directory.
Creates
| Arg / flag | Value name | Type | Default | Meaning |
|---|---|---|---|---|
| name (positional) | <name> | String | Required. Workspace directory to create at ./<name>/. |
./<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>.cerulion workspace init
cerulion workspace init
Initialize a workspace in place.
Initializes a workspace at
| Arg / flag | Value name | Type | Default | Meaning |
|---|---|---|---|---|
| location (positional) | [location] | String | . | Directory to initialize in place (defaults to the current directory). |
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>.node
Subcommands:create, delete, modify, build, stage, run, list, info. All require workspace discovery.
cerulion node create
cerulion node create
Create a node type.
Schema is accepted in both
| 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. |
| raw FFI | --raw-ffi | bool | false | Generate the raw extern "C" FFI template instead of the #[cerulion_node] macro template. |
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.cerulion node delete
cerulion node delete
Delete a node type.
Removes
| Arg | Value name | Type | Meaning |
|---|---|---|---|
| node type (positional) | <node_type> | String | Required. Node type to delete. |
nodes/<node_type>/ (recursive) and the workspace member entry. Errors NodeNotFound if absent. Prints Deleted node type '<node_type>'.cerulion node modify
cerulion node modify
Modify an existing node type in place.
Mutates the nodeβs
| 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. |
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'.The only user surface for setting external triggering is
--policy external.cerulion node build
cerulion node build
Build a node crate.
Runs
| Flag | Long | Type | Default | Meaning |
|---|---|---|---|---|
| node type | (positional) | <node_type> | Required. Node type to build. | |
| release | --release | bool | false | Build in release mode. |
cargo build -p <node_type> (adds --release if set) in the workspace root. Errors BuildFailed (with cargo stderr) on failure. Prints Built '<node_type>'.cerulion node stage
cerulion node stage
Append a node instance to a graph YAML file.
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
| 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. |
Staged '<type>' into graph '<graph>'.cerulion node run
cerulion node run
Smoke-run a single node.
Creates a hidden temp graph
| 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. |
__temp_<type>, stages the node, runs it in live mode (validation skipped), and deletes the temp graph YAML on exit. Ctrl+C stops it.cerulion node list
cerulion node list
List node types.No arguments. Prints a table with columns
TYPE INPUTS OUTPUTS POLICY (counts plus a short policy label). Empty workspace prints No nodes found.cerulion node info
cerulion node info
Show details for a node type.
Prints
| Arg | Value name | Type | Meaning |
|---|---|---|---|
| node type (positional) | <node_type> | String | Required. Node type to inspect. |
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).graph
Subcommands:create, run, validate, list.
cerulion graph create
cerulion graph create
Create a graph file.
Creates
| 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. |
graphs/<name>.yaml. Errors if the graph already exists. Prints Created graph '<name>'.cerulion graph run
cerulion graph run
Run a graph.
Loads cdylibs, builds the runtime, and runs the graph until Ctrl+C or a node requests shutdown. In the default live mode (
| 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. |
--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.cerulion graph validate
cerulion graph validate
Validate a graph.
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.
| 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. |
cerulion graph list
cerulion graph list
List graphs.No arguments. Lists graph names (file stems of
*.yaml), sorted. Empty prints No graphs found.topic
Uses iceoryx2 service discovery: enumerates services ending in/data (Cerulion creates {topic}/data and {topic}/event per topic). No workspace required.
cerulion topic list
cerulion topic list
List active topics.Lists active topic names (sorted). Header
TOPIC. Empty prints No active topics.cerulion topic info
cerulion topic info
Show topic info.
Prints the topic info string.
| Arg | Value name | Type | Meaning |
|---|---|---|---|
| topic (positional) | <topic> | String | Required. Topic to inspect. |
cerulion topic echo
cerulion topic echo
Print messages from a topic.
Subscribes and prints messages until Ctrl+C. Pretty-prints
| Arg | Value name | Type | Meaning |
|---|---|---|---|
| topic (positional) | <topic> | String | Required. Topic to subscribe to. |
std_msgs/String and sensor_msgs/Image (by FNV-1a schema hash); hex preview otherwise.cerulion topic hz
cerulion topic hz
Measure publish rate.
Measures the publish rate until Ctrl+C.
| Arg | Value name | Type | Meaning |
|---|---|---|---|
| topic (positional) | <topic> | String | Required. Topic to measure. |
schema
Subcommands:create, delete, info.
cerulion schema create
cerulion schema create
Create a schema file.
Creates
| Arg | Value name | Type | Meaning |
|---|---|---|---|
| name (positional) | <name> | String | Required. Schema name β schemas/<PascalName>.yaml. |
schemas/<PascalName>.yaml with a schemas: skeleton (description plus a fields: comment). Errors if the schema exists. Prints Created schema '<name>'.cerulion schema delete
cerulion schema delete
Delete a schema file.
Removes
| Arg | Value name | Type | Meaning |
|---|---|---|---|
| name (positional) | <name> | String | Required. Schema to delete. |
schemas/<name>.yaml. Errors SchemaNotFound. Prints Deleted schema '<name>'.cerulion schema info
cerulion schema info
Show schema details.
First tries a ROS2
| Arg | Value name | Type | Meaning |
|---|---|---|---|
| name (positional) | <name> | String | Required. Schema name. Accepts qualified ROS2 names like sensor_msgs::Image. |
.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...).tui
trace inspect
| 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). |
trace_*.jsonl bag files (lexicographic order) and prints <topic> seq=<N> t=<ts>ns schema=0x<HASH> per record.