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
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
cerulion workspace create
cerulion workspace create
Create a new workspace directory.
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>.cerulion workspace init
cerulion workspace init
Initialize a workspace in place.
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>.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
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
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
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
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
Staged '<type>' into graph '<graph>'.cerulion node run
cerulion node run
Smoke-run a single node.
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.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
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
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 (
--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.
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.
cerulion topic echo
cerulion topic echo
Print messages from a topic.
Subscribes and prints messages until Ctrl+C. Pretty-prints
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.
schema
Subcommands:create, delete, info.
cerulion schema create
cerulion schema create
Create a schema file.
Creates
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
schemas/<name>.yaml. Errors SchemaNotFound. Prints Deleted schema '<name>'.cerulion schema info
cerulion schema info
Show schema details.
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...).tui
trace inspect
Reads
trace_*.jsonl bag files (lexicographic order) and prints <topic> seq=<N> t=<ts>ns schema=0x<HASH> per record.