CLI Reference

The horus command gives you everything you need to build, run, and manage your applications.

Quick Reference

# Project Management
horus init                 # Initialize workspace in current directory
horus new <name>           # Create a new project
horus run [files...]       # Build and run your app
horus build [files...]     # Build without running
horus test [filter]        # Run tests
horus check [path]         # Validate horus.toml and workspace
horus clean                # Clean build artifacts and shared memory
horus lock                 # Generate or verify horus.lock
horus launch <file>        # Launch multiple nodes from YAML

# Monitoring & Debugging
horus monitor [port]       # Monitor your system (web or TUI)
horus topic <command>      # Topic introspection (list, echo, info, hz, pub)
horus node <command>       # Node management (list, info, kill, restart, pause, resume)
horus service <command>    # Service interaction (list, call, info, find)
horus action <command>     # Action introspection (list, info, send-goal, cancel-goal)
horus log [node]           # View and filter logs
horus blackbox             # Inspect BlackBox flight recorder (alias: bb)

# Coordinate Frames
horus frame <command>      # Transform Frames (list, echo, tree, info, can, hz) (alias: tf)

# Dependencies
horus add <name>           # Add a dependency to horus.toml (auto-detects source)
horus remove <name>        # Remove a dependency from horus.toml

# Package Management
horus install <name>       # Install a standalone package or plugin from registry
horus uninstall <name>     # Uninstall a standalone package or plugin
horus list [query]         # List/search packages (--global, --all, --json)
horus search <query>       # Search for available packages/plugins (--category, --json)
horus info <name>          # Show detailed info about a package or plugin (--json)
horus update [package]     # Update project dependencies (--dry-run)
horus publish              # Publish current package to registry (--dry-run)
horus unpublish <pkg>      # Unpublish a package from registry (--yes)
horus yank <pkg@ver>       # Yank a package version (--reason)
horus deprecate <pkg>      # Mark a package as deprecated (--message)
horus owner <command>      # Manage package owners (list, add, remove, transfer)
horus cache <command>      # Cache management (info, list, clean, purge)

# Parameters & Messages
horus param <command>      # Parameter management (get, set, list, delete, reset, dump, load, save)
horus msg <command>        # Message type introspection (list, info, hash)

# Development
horus fmt                  # Format code (Rust + Python)
horus lint                 # Lint code (clippy + ruff/pylint)
horus doc                  # Generate documentation
horus bench [filter]       # Run benchmarks
horus deps <command>       # Dependency insight (tree, why, outdated, audit)

# Maintenance
horus doctor               # Comprehensive ecosystem health check
horus doctor --fix         # Install missing toolchains and system deps
horus self update           # Update the horus CLI to latest version
horus config <command>     # View/edit horus.toml settings (get, set, list)
horus migrate              # Migrate project to unified horus.toml format

# Advanced
horus deploy [target]      # Deploy to remote robot
horus record <command>     # Record/replay for debugging and testing
horus scripts [name]       # Run a script from horus.toml [scripts]

# Plugins
horus plugin <command>     # Plugin management (enable, disable, verify)

# Auth
horus auth <command>       # Authentication (login, api-key, signing-key, logout, whoami)

horus init - Initialize Workspace

What it does: Initializes a HORUS workspace in the current directory, creating the necessary configuration files.

Why it's useful: Quickly set up an existing directory as a HORUS project without creating new files from templates.

Basic Usage

# Initialize in current directory (uses directory name)
horus init

# Initialize with custom name
horus init --name my_robot

All Options

horus init [OPTIONS]

Options:
  -n, --name <NAME>    Workspace name (defaults to directory name)

Examples

Initialize existing code as HORUS project:

cd ~/my-robot-code
horus init
# Creates horus.toml with project configuration

Initialize with specific name:

horus init --name sensor_array

What Gets Created

Running horus init creates:

  • horus.toml - Project config with name and version

This is useful when you have existing code and want to add HORUS support, or when setting up a workspace that will contain multiple HORUS projects.


horus new - Create Projects

What it does: Creates a new HORUS project with all the boilerplate set up for you.

Why it's useful: Minimal configuration required. Select a language and begin development.

Basic Usage

# Interactive mode (asks you questions)
horus new my_project

# Rust with node! macro (recommended for reduced boilerplate)
horus new my_project --macro

# Python project
horus new my_project --python

All Options

horus new <NAME> [OPTIONS]

Options:
  -m, --macro              Rust with node! macro (less boilerplate)
  -r, --rust               Plain Rust project
  -p, --python             Python project
  -w, --workspace          Create a workspace project with multiple crates
  -l, --lib                Create a library crate (instead of binary)
  -o, --output <PATH>      Where to create it (default: current directory)

Examples

Start with Rust + macros (easiest):

horus new temperature_monitor --macro
cd temperature_monitor
horus run

Python for prototyping:

horus new sensor_test --python
cd sensor_test
python main.py

Put it somewhere specific:

horus new robot_controller --output ~/projects/robots

horus run - Build and Run

What it does: Compiles your code and runs it. Handles all the build tools for you.

Why it's useful: One command works for Rust and Python. Language is auto-detected from native build files (Cargo.toml for Rust, pyproject.toml for Python). For Rust, it builds with Cargo. For Python, it handles the appropriate tooling.

Basic Usage

# Run current directory (finds main.rs or main.py)
horus run

# Run specific file
horus run src/controller.rs

# Run optimized (release mode)
horus run --release

All Options

horus run [FILES...] [OPTIONS] [-- ARGS]

Options:
  -r, --release            Optimize for speed (recommended for benchmarks)
  -c, --clean              Remove cached build artifacts and dependencies
                           (Use after updating HORUS or when compilation fails)
  -q, --quiet              Suppress progress indicators
  -p, --package <NAME>     Build and run a specific workspace member
  -d, --drivers <LIST>     Override detected drivers (comma-separated)
                           Example: --drivers camera,lidar,imu
  -e, --enable <LIST>      Enable capabilities (comma-separated)
                           Example: --enable cuda,editor,python
      --record <NAME>      Enable recording for this session
  -- <ARGS>                Arguments for your program

Using --enable for Capabilities

The --enable flag lets you quickly enable features without editing horus.toml:

# Enable CUDA GPU acceleration
horus run --enable cuda

# Enable multiple capabilities
horus run --enable cuda,editor,python

# Combine with hardware features
horus run --enable gpio,i2c --release

Available capabilities:

CapabilityDescription
cuda, gpuCUDA GPU acceleration
editorScene editor UI
python, pyPython bindings
headlessNo rendering (for training)
gpio, i2c, spi, can, serialHardware interfaces
opencvOpenCV backend
realsenseIntel RealSense support
fullAll features

Or configure in horus.toml:

enable = ["cuda", "editor"]

Why --release Matters

Debug builds have significantly higher overhead than release builds due to runtime checks and lack of optimizations.

Debug mode (default): Fast compilation, slower execution

  • Use case: Development iteration
  • Typical tick time: 60-200μs
  • Includes overflow checks, bounds checking, assertions

Release mode (--release): Slower compilation, optimized execution

  • Use case: Performance testing, benchmarks, production deployment
  • Typical tick time: 1-3μs
  • Full compiler optimizations enabled

Common Mistake:

horus run  # Debug mode
# You see: [IPC: 1862ns | Tick: 87μs] - Looks slow!

horus run --release  # Release mode
# You see: [IPC: 947ns | Tick: 2μs] - Actually fast!

The tick time difference is dramatic:

  • Debug: 60-200μs per tick (too slow for real-time control)
  • Release: 1-3μs per tick (production-ready performance)

Rule of thumb: Always use --release when:

  • Measuring performance
  • Running benchmarks
  • Testing real-time control loops
  • Deploying to production
  • Wondering "why is HORUS slow?"

Why --clean Matters

The --clean flag removes the .horus/target/ directory, which contains cached build artifacts and dependencies.

When to use --clean:

  1. After updating HORUS - Most common use case

    # You updated horus CLI to a new version
    horus run --clean
    

    This fixes version mismatch errors like:

    error: the package `horus` depends on `horus_core 0.1.0`,
    but `horus_core 0.1.3` is installed
    
  2. Compilation fails mysteriously

    horus run --clean
    # Sometimes cached state gets corrupted
    
  3. Dependencies changed

    # You modified Cargo.toml dependencies
    horus run --clean
    

What it does:

  • Removes .horus/target/ (build artifacts)
  • Removes cached lock files
  • Forces fresh dependency resolution
  • Next build rebuilds everything from scratch

Trade-off:

  • First build after --clean is slower (5-30 seconds)
  • Subsequent builds are fast again (incremental compilation)

Note: The --clean flag only affects the current project's .horus/ directory, not the global ~/.horus/ cache.

Examples

Daily development:

horus run
# Fast iteration, slower execution

Testing performance:

horus run --release
# See real speed

Build for CI without running (use horus build):

horus build --release

Fresh build (when things act weird or after updating HORUS):

horus run --clean --release

After updating HORUS CLI (fixes version mismatch errors):

# Clean removes cached dependencies from .horus/target/
horus run --clean

Pass arguments to your program:

horus run -- --config robot.yaml --verbose

Important: Single-File Projects Only

horus run is designed for single-file HORUS projects (main.rs or main.py). It creates a temporary workspace in .horus/ and automatically handles dependencies.

What works with horus run:

  • Single main.rs with all nodes defined in one file
  • Simple Python scripts (main.py)

What doesn't work:

  • Multi-crate Cargo workspaces
  • Projects with multiple Cargo.toml files
  • Complex module structures with separate crate directories

For multi-crate projects, use cargo directly:

cd your_multi_crate_project
cargo build --release
cargo run --release

Example of a proper single-file structure:

// main.rs - everything in one file
use horus::prelude::*;

struct SensorNode { /* ... */ }
impl Node for SensorNode { /* ... */ }

struct ControlNode { /* ... */ }
impl Node for ControlNode { /* ... */ }

fn main() -> Result<()> {
    let mut scheduler = Scheduler::new();
    scheduler.add(SensorNode::new()?).order(0).build()?;
    scheduler.add(ControlNode::new()?).order(1).build()?;
    scheduler.run()
}

Concurrent Multi-Process Execution

HORUS supports running multiple node files concurrently as separate processes using glob patterns. This is ideal for distributed robotics systems where nodes need to run independently.

Basic Usage:

horus run "nodes/*.py"          # Run all Python nodes concurrently
horus run "src/*.rs"            # Run all Rust nodes concurrently

How it works:

  1. Phase 1 (Build): Builds all files sequentially, respecting Cargo's file lock
  2. Phase 2 (Execute): Spawns all processes concurrently with their own schedulers
  3. Each process communicates via HORUS shared memory IPC

Features:

  • -Color-coded output: Each node is prefixed with [node_name] in a unique color
  • -Graceful shutdown: Ctrl+C cleanly terminates all processes
  • -Multi-language: Works with Rust and Python
  • -Automatic detection: No flags needed, just use glob patterns

Example output:

$ horus run "nodes/*.py"
 Executing 3 files concurrently:
  1. nodes/sensor.py (python)
  2. nodes/controller.py (python)
  3. nodes/logger.py (python)

 Phase 1: Building all files...
 Phase 2: Starting all processes...
   Started [sensor]
   Started [controller]
   Started [logger]

 All processes running. Press Ctrl+C to stop.

[sensor] Sensor reading: 25.3°C
[controller] Motor speed: 45%
[logger] System operational
[sensor] Sensor reading: 26.1°C
[controller] Motor speed: 50%
[logger] System operational

When to use concurrent execution:

  • Multi-node systems where each node is in a separate file
  • Distributed control architectures (similar to ROS nodes)
  • Testing multiple nodes simultaneously
  • Microservices-style robotics architectures

When to use single-process execution:

  • All nodes in one file (typical for simple projects)
  • Projects requiring predictable scheduling across all nodes
  • Maximum performance with minimal overhead

Important: Each process runs its own scheduler. Nodes communicate through HORUS shared memory topics, not direct function calls.

Common Errors

ErrorCauseFix
No horus.toml foundNot in a project directorycd into your project or run horus init
No main source file foundMissing src/main.rs or src/main.pyCreate the file or specify: horus run src/your_file.rs
Compilation failedRust/Python syntax errorsFix the errors shown in the output
Permission denied on shared memorySHM permissionsRun horus doctor to diagnose, then fix OS-level permissions
Address already in useAnother horus process runninghorus clean --shm to clear stale SHM

horus check - Validate Project

What it does: Validates horus.toml, source files, and the workspace configuration.

Why it's useful: Quickly diagnose configuration issues, missing dependencies, or environment problems before building.

Basic Usage

# Check current directory
horus check

# Check a specific path
horus check path/to/project

# Quiet mode (errors only)
horus check --quiet

All Options

horus check [OPTIONS] [PATH]

Arguments:
  [PATH]  Path to file, directory, or workspace (default: current directory)

Options:
  -q, --quiet    Only show errors, suppress warnings
  -h, --help     Print help

Examples

Validate before building:

horus check
# Validates horus.toml, build files, and environment

CI/CD validation:

#!/bin/bash
if ! horus check --quiet; then
  echo "Validation failed"
  exit 1
fi
horus build --release

Related:


horus monitor - Monitor Everything

What it does: Opens a visual monitor showing all your running nodes, messages, and performance.

Why it's useful: Debug problems visually. See message flow in real-time. Monitor performance.

Basic Usage

# Web monitor (opens in browser)
horus monitor

# Different port
horus monitor 8080

# Text-based (for SSH)
horus monitor --tui

# Reset monitor password before starting
horus monitor --reset-password

What You See

The monitor shows:

  • All running nodes - Names, status, tick rates
  • Message flow - What's talking to what
  • Performance - CPU, memory, latency per node
  • Topics - All active communication channels
  • Graph view - Visual network of your system

Examples

Start monitoring (in a second terminal):

# Terminal 1: Run your app
horus run --release

# Terminal 2: Watch it
horus monitor

Access from your phone:

horus monitor
# Visit http://your-computer-ip:3000 from phone

Monitor over SSH:

ssh robot@192.168.1.100
horus monitor --tui

See Monitor Guide for detailed features.


horus search - Search Packages

Alias: horus s

What it does: Search the HORUS registry for available packages and plugins.

Why it's useful: Find drivers, libraries, and plugins before installing them.

All Options

horus search <QUERY> [OPTIONS]

Arguments:
  <QUERY>  Search query (e.g., "camera", "lidar", "motor")

Options:
  -c, --category <CAT>  Filter by category (camera, lidar, imu, motor, servo, bus, gps, simulation, cli)
      --json             Output as JSON

Examples

Search for packages:

horus search lidar

Filter by category:

horus search driver --category camera

Machine-readable output:

horus search motor --json

horus info - Package/Plugin Info

What it does: Shows detailed information about a package or plugin, including version, description, dependencies, and metadata.

Why it's useful: Inspect a package before installing, or check details of an installed package.

All Options

horus info <NAME> [OPTIONS]

Arguments:
  <NAME>  Package or plugin name

Options:
      --json    Output as JSON

Examples

Show package details:

horus info pid-controller

JSON output for tooling:

horus info rplidar-driver --json

horus list - List Installed Packages

What it does: Lists installed packages and plugins in the current project or globally.

Why it's useful: See what is installed, verify versions, and audit dependencies.

All Options

horus list [OPTIONS]

Options:
  -g, --global    List global scope packages only
  -a, --all       List all (local + global)
      --json      Output as JSON

Examples

List local packages:

horus list

List everything (local + global):

horus list --all

List global packages as JSON:

horus list --global --json

horus update - Update Packages

What it does: Updates project dependencies, the horus CLI tool itself, and installed plugins.

Why it's useful: Keep dependencies current, apply security patches, and upgrade the CLI without manual reinstallation.

All Options

horus update [PACKAGE] [OPTIONS]

Arguments:
  [PACKAGE]  Specific package to update (updates all deps if omitted)

Options:
  -g, --global     Update global scope packages
      --dry-run    Show what would be updated without making changes
      --self       Update the horus CLI tool itself
      --plugins    Update installed plugins to latest versions

Examples

Update all project dependencies:

horus update

Update a specific package:

horus update pid-controller

Update the CLI tool itself:

horus update --self

Update all plugins:

horus update --plugins

Preview updates without applying:

horus update --dry-run

Update global packages:

horus update --global

horus publish - Publish Package

What it does: Publishes the current package to the HORUS registry. Validates the package, builds it, and uploads to the registry.

Why it's useful: Share your drivers, libraries, and tools with the community or your team.

All Options

horus publish [OPTIONS]

Options:
      --dry-run    Validate and build the package without actually publishing

Examples

Publish to registry:

# First login
horus auth login

# Then publish from your project directory
horus publish

Validate without publishing:

horus publish --dry-run

horus unpublish - Unpublish Package

What it does: Removes a published package version from the HORUS registry.

Why it's useful: Retract a broken release or remove a package that should no longer be available.

All Options

horus unpublish <PACKAGE> [OPTIONS]

Arguments:
  <PACKAGE>  Package name (supports name@version syntax, e.g. my-pkg@1.0.0)

Options:
  -y, --yes    Skip confirmation prompt

Examples

Unpublish a specific version:

horus unpublish my-package@1.0.0

Skip confirmation:

horus unpublish my-package@1.0.0 --yes

horus auth signing-key - Generate Signing Keys

What it does: Generates an Ed25519 signing key pair for package signing. The private key is stored locally and the public key can be shared or uploaded to the registry.

Why it's useful: Sign your packages to prove authenticity. Users can verify that packages have not been tampered with.

Migration: horus keygen still works but is deprecated. Use horus auth signing-key instead.

Basic Usage

horus auth signing-key

Examples

Generate a new key pair:

horus auth signing-key
# Generates Ed25519 key pair
# Private key saved to ~/.horus/keys/
# Public key printed to stdout

horus auth - Authentication & Keys

What it does: Authenticate with the registry, manage API keys, and generate signing keys.

Why it's useful: Secure access to the package registry for publishing and downloading.

Commands

# Login with GitHub
horus auth login

# Generate API key (for CI/CD publishing)
horus auth api-key

# Generate Ed25519 signing key pair (for package signing)
horus auth signing-key

# Check who you are
horus auth whoami

# Logout
horus auth logout

# Manage API keys
horus auth keys list
horus auth keys revoke <key_id>

Examples

First time setup:

horus auth login
# Opens browser for GitHub login

Check you're logged in:

horus auth whoami

Generate API key for CI/CD:

horus auth api-key --name github-actions --environment ci-cd
# Save the generated key in your CI secrets

Generate signing key for package integrity:

horus auth signing-key
# Ed25519 key pair saved to ~/.horus/keys/

Logout:

horus auth logout

horus build - Build Without Running

What it does: Compiles your project without executing it.

Why it's useful: Validate compilation, prepare for deployment, or integrate with CI/CD pipelines.

Basic Usage

# Build current project
horus build

# Build in release mode
horus build --release

# Clean build (remove cached artifacts first)
horus build --clean

All Options

horus build [FILES...] [OPTIONS]

Options:
  -r, --release            Build in release mode (optimized)
  -c, --clean              Clean before building
  -q, --quiet              Suppress progress indicators
  -p, --package <NAME>     Build a specific workspace member
  -d, --drivers <LIST>     Override detected drivers (comma-separated)
  -e, --enable <LIST>      Enable capabilities (comma-separated)
  -h, --help               Print help

Examples

CI/CD build validation:

horus build --release
# Exit code 0 = success, non-zero = failure

Clean release build for deployment:

horus build --clean --release

Common Errors

ErrorCauseFix
No horus.toml foundNot in a project directoryRun horus init or cd into project
error[E0432]: unresolved importMissing dependencyhorus add <crate> --source crates.io
.horus/Cargo.toml generation failedMalformed horus.tomlhorus check to validate
linker 'cc' not foundMissing C compilersudo apt install build-essential

horus test - Run Tests

What it does: Runs your HORUS project's test suite.

Why it's useful: Validate functionality, run integration tests with simulation, and ensure code quality.

Basic Usage

# Run all tests
horus test

# Run tests matching a filter
horus test my_node

# Run with parallel execution
horus test --parallel

# Run simulation tests
horus test --sim

All Options

horus test [OPTIONS] [FILTER]

Arguments:
  [FILTER]  Test name filter (runs tests matching this string)

Options:
  -r, --release            Run tests in release mode
      --parallel           Allow parallel test execution
      --sim                Enable simulation mode (no hardware required)
      --integration        Run integration tests (tests marked #[ignore])
      --nocapture          Show test output
  -j, --test-threads <N>   Number of test threads (default: 1)
      --no-build           Skip the build step
      --no-cleanup         Skip shared memory cleanup after tests
  -v, --verbose            Verbose output
  -d, --drivers <LIST>     Override detected drivers (comma-separated)
  -e, --enable <LIST>      Enable capabilities (comma-separated)
  -h, --help               Print help

Examples

Run specific tests:

horus test sensor_node --nocapture

Fast parallel test run:

horus test --parallel --release

Integration tests with simulator:

horus test --integration --sim

horus clean - Clean Build Artifacts

What it does: Removes build artifacts, cached dependencies, and shared memory files.

Why it's useful: Fix corrupted builds, reclaim disk space, or reset shared memory after crashes.

Basic Usage

# Clean everything (build + shared memory + cache)
horus clean --all

# Only clean shared memory
horus clean --shm

# Preview what would be cleaned
horus clean --dry-run

All Options

horus clean [OPTIONS]

Options:
      --shm      Only clean shared memory
  -a, --all      Clean everything (build cache + shared memory + horus cache)
  -n, --dry-run  Show what would be cleaned without removing anything
  -h, --help     Print help
  -V, --version  Print version

Examples

After a crash (clean stale shared memory):

horus clean --shm

Full reset before deployment:

horus clean --all
horus build --release

horus topic - Topic Introspection

What it does: Inspect, monitor, and interact with HORUS topics (shared memory communication channels).

Why it's useful: Debug message flow, verify data publishing, and measure topic rates.

Subcommands

horus topic list              # List all active topics
horus topic echo <topic>      # Print messages as they arrive
horus topic info <topic>      # Show topic details (type, publishers, subscribers)
horus topic hz <topic>        # Measure publishing rate
horus topic pub <topic> <msg> # Publish a message

Examples

List all topics:

horus topic list
# Output:
# cmd_vel (CmdVel) - 2 publishers, 1 subscriber
# scan (LaserScan) - 1 publisher, 3 subscribers
# odom (Odometry) - 1 publisher, 1 subscriber

Monitor a topic in real-time:

horus topic echo scan
# Prints each LaserScan message as it arrives

Check publishing rate:

horus topic hz cmd_vel
# Output: average rate: 50.0 Hz, min: 49.2, max: 50.8

Publish test message:

horus topic pub cmd_vel '{"stamp_nanos": 0, "linear": 1.0, "angular": 0.5}'

horus node - Node Management

What it does: List, inspect, and control running HORUS nodes.

Why it's useful: Debug node states, restart misbehaving nodes, or pause nodes during testing.

Subcommands

horus node list               # List all running nodes
horus node info <node>        # Show detailed node information
horus node kill <node>        # Terminate a node
horus node restart <node>     # Restart a node
horus node pause <node>       # Pause a node's tick execution
horus node resume <node>      # Resume a paused node

Examples

List all running nodes:

horus node list
# Output:
# NAME              PID     RATE   CPU    MEMORY   STATUS
# SensorNode        12345   100Hz  1.2%   10MB     Running
# ControllerNode    12346   50Hz   2.5%   15MB     Running
# LoggerNode        12347   10Hz   0.1%   5MB      Paused

Get detailed node info:

horus node info SensorNode
# Shows: tick count, error count, subscribed topics, published topics

Restart a stuck node:

horus node restart ControllerNode

Pause/resume for debugging:

horus node pause SensorNode
# ... inspect state ...
horus node resume SensorNode

horus service - Service Interaction

Alias: horus srv

What it does: Inspect and interact with HORUS services (request/response communication channels).

When to use: Debug service calls, verify server availability, or test request/response workflows from the command line.

Subcommands

SubcommandDescription
listList all active services
call <name> <json>Call a service with a JSON request
info <name>Show type info and status for a service
find <filter>Find services matching a name filter

All Options

horus service list [-v, --verbose] [--json]
horus service call <name> <request_json> [-t, --timeout <SECS>]
horus service info <name>
horus service find <filter>
SubcommandFlagDescription
list-v, --verboseShow detailed information (servers, clients, topics)
list--jsonOutput as JSON
call-t, --timeout <SECS>Timeout in seconds (default: 5.0)

Examples

List all services:

horus service list
# Output:
# NAME                             SERVERS  CLIENTS  STATUS
# add_two_ints                           1        1  active
# get_map                                1        0  active

Call a service:

horus service call add_two_ints '{"a": 3, "b": 4}'
# Response received:
# { "sum": 7 }

Call with custom timeout:

horus service call get_map '{}' --timeout 10.0

Show service details:

horus service info add_two_ints
# Name: add_two_ints
# Request topic: add_two_ints/request
# Response topic: add_two_ints/response
# Status: active
# Servers: 1
# Clients: 1

Find services by name:

horus service find map
# get_map
# save_map

horus action - Action Introspection

Alias: horus a

What it does: Inspect and interact with long-running action servers. Actions use a goal/feedback/result protocol for tasks that take time to complete.

When to use: Debug navigation goals, manipulation tasks, or any action-based node. Send goals from the command line and monitor progress.

Subcommands

SubcommandDescription
listList all active actions
info <name>Show action details (topics, publishers, subscribers)
send-goal <name> <json>Send a goal to an action server
cancel-goal <name>Cancel an active goal

All Options

horus action list [-v, --verbose] [--json]
horus action info <name>
horus action send-goal <name> <goal_json> [-w, --wait] [-t, --timeout <SECS>]
horus action cancel-goal <name> [-i, --goal-id <ID>]
SubcommandFlagDescription
list-v, --verboseShow detailed information (topics, publishers)
list--jsonOutput as JSON
send-goal-w, --waitWait for and display the result
send-goal-t, --timeout <SECS>Timeout when waiting for result (default: 30.0)
cancel-goal-i, --goal-id <ID>Specific goal ID to cancel (cancels all if omitted)

Action Topics

Each action <name> creates five sub-topics:

TopicDirectionPurpose
<name>.goalClient -> ServerClients send goals here
<name>.cancelClient -> ServerClients request cancellation
<name>.statusServer -> ClientServer broadcasts goal states
<name>.feedbackServer -> ClientServer sends progress updates
<name>.resultServer -> ClientServer sends final result

Examples

List all actions:

horus action list
# Output:
# NAME                                     GOALS  TOPICS
# navigate_to_pose                              2  5/5 topics
# pick_object                                   1  3/5 topics

Send a navigation goal:

horus action send-goal navigate_to_pose '{"target_x": 5.0, "target_y": 3.0}'

Send a goal and wait for the result:

horus action send-goal navigate_to_pose '{"target_x": 5.0, "target_y": 3.0}' --wait
# Sending goal to action: navigate_to_pose
#   Goal ID: abc12345
#
# Goal sent
#   Feedback: {"progress": 0.5}
#   Status: Running
#   Feedback: {"progress": 1.0}
#   Status: Succeeded
#
# Result:
# { "success": true, "distance_traveled": 5.83 }

Send a goal with custom timeout:

horus action send-goal navigate_to_pose '{"x": 10.0}' --wait --timeout 60.0

Cancel a specific goal:

horus action cancel-goal navigate_to_pose --goal-id abc-123-def

Cancel all goals on an action:

horus action cancel-goal navigate_to_pose

Get action details:

horus action info navigate_to_pose
# Action Information
#   Name: navigate_to_pose
#   Topics:
#     navigate_to_pose/goal        -- clients send goals here
#     navigate_to_pose/cancel      -- clients request cancellation
#     navigate_to_pose/status      -- server broadcasts goal states
#     navigate_to_pose/feedback    -- server sends progress
#     navigate_to_pose/result      -- server sends final result
#   Goal publishers (clients): 2
#   Result subscribers (clients): 1

horus log - View and Filter Logs

What it does: View, filter, and follow HORUS system logs.

Why it's useful: Debug issues, monitor specific nodes, and track errors in real-time.

Basic Usage

# View all recent logs
horus log

# Filter by node
horus log SensorNode

# Follow logs in real-time
horus log --follow

# Show only errors
horus log --level error

All Options

horus log [OPTIONS] [NODE]

Arguments:
  [NODE]  Filter by node name

Options:
  -l, --level <LEVEL>  Filter by log level (trace, debug, info, warn, error)
  -s, --since <SINCE>  Show logs from last duration (e.g., "5m", "1h", "30s")
  -f, --follow         Follow log output in real-time
  -n, --count <COUNT>  Number of recent log entries to show
      --clear          Clear logs instead of viewing
      --clear-all      Clear all logs (including file-based logs)
  -h, --help           Print help

Examples

Follow logs from a specific node:

horus log SensorNode --follow

View errors from last 10 minutes:

horus log --level error --since 10m

Show last 50 warnings and errors:

horus log --level warn --count 50

horus param - Parameter Management

What it does: Manage node parameters at runtime (get, set, list, dump, save, load).

Why it's useful: Tune robot behavior without recompiling, persist configurations, and debug parameter values.

Subcommands

horus param list                  # List all parameters
horus param get <key>             # Get parameter value
horus param set <key> <value>     # Set parameter value
horus param delete <key>          # Delete a parameter
horus param reset                 # Reset all parameters to defaults
horus param load <file>           # Load parameters from YAML file
horus param save [-o <file>]      # Save parameters to YAML file
horus param dump                  # Dump all parameters as YAML to stdout

Examples

List all parameters:

horus param list
# Output:
# /SensorNode/sample_rate: 100
# /SensorNode/filter_size: 5
# /ControllerNode/kp: 1.5
# /ControllerNode/ki: 0.1

Tune a controller at runtime:

horus param set ControllerNode kp 2.0
horus param set ControllerNode ki 0.2

Save and restore configuration:

# Save current params
horus param save robot_config.yaml

# Later, restore them
horus param load robot_config.yaml

horus tf - Transform Frames (Coordinate Transforms)

What it does: Inspect and monitor coordinate frame transforms (similar to ROS tf).

Why it's useful: Debug transform chains, visualize frame relationships, and verify sensor mounting.

Subcommands

# Introspection
horus tf list                    # List all frames
horus tf echo <source> <target>  # Echo transform between two frames
horus tf tree                    # Show frame tree hierarchy
horus tf info <frame>            # Detailed frame information
horus tf can <source> <target>   # Check if transform is possible
horus tf hz                      # Monitor frame update rates

# Recording & Replay
horus tf record -o <file>        # Record transforms to a .tfr file
horus tf play <file>             # Replay a .tfr recording
horus tf diff <file1> <file2>    # Compare two .tfr recordings

# Calibration
horus tf tune <frame>            # Interactively tune a static frame's offset
horus tf calibrate               # Compute sensor-to-base transform from point pairs (SVD)
horus tf hand-eye                # Solve hand-eye calibration (AX=XB) from pose pairs

Examples

View frame tree:

horus tf tree
# Output:
# world
# └── base_link
#     ├── laser_frame
#     ├── camera_frame
#     └── imu_frame

Monitor a transform:

horus tf echo laser_frame world
# Prints: translation [x, y, z] rotation [qx, qy, qz, qw]

Check transform chain:

horus tf can laser_frame world
# Output: Yes, chain: laser_frame -> base_link -> world

Recording & Replay

Record transforms for offline analysis, comparison, or replay.

# Record transforms for 30 seconds
horus tf record -o session1.tfr -d 30

# Replay at half speed
horus tf play session1.tfr -s 0.5

# Compare two recordings
horus tf diff session1.tfr session2.tfr --threshold-m 0.01

Options:

SubcommandFlagDescription
record-o, --output <FILE>Output .tfr file path (required)
record-d, --duration <SECS>Maximum recording duration in seconds
play-s, --speed <MULT>Playback speed multiplier (default: 1.0)
diff--threshold-m <M>Translation difference threshold in meters (default: 0.001)
diff--threshold-deg <DEG>Rotation difference threshold in degrees (default: 0.1)
diff--jsonOutput as JSON

Calibration

Calibrate sensor mounting and hand-eye transforms directly from the CLI.

Tune a static frame interactively:

# Adjust laser_frame offset with fine steps
horus tf tune laser_frame --step-m 0.001 --step-deg 0.1

Compute sensor-to-base transform from known point correspondences:

# CSV format: sensor_x,sensor_y,sensor_z,world_x,world_y,world_z
horus tf calibrate --points-file calibration_points.csv

Solve hand-eye calibration (AX=XB):

horus tf hand-eye --robot-poses robot.csv --sensor-poses sensor.csv

Options:

SubcommandFlagDescription
tune--step-m <M>Translation step size in meters (default: 0.001)
tune--step-deg <DEG>Rotation step size in degrees (default: 0.1)
calibrate--points-file <FILE>CSV file with point pairs (sensor_x,y,z,world_x,y,z)
hand-eye--robot-poses <FILE>CSV file with robot poses
hand-eye--sensor-poses <FILE>CSV file with sensor poses

horus msg - Message Type Introspection

What it does: Inspect HORUS message type definitions and schemas.

Why it's useful: Understand message structures, debug serialization issues, and verify type compatibility.

Subcommands

horus msg list               # List all message types
horus msg info <type>        # Show message definition
horus msg hash <type>        # Show hash (for compatibility checking)

Examples

List available message types:

horus msg list
# Output:
# CmdVel (horus_library::messages::cmd_vel)
# LaserScan (horus_library::messages::sensor)
# Odometry (horus_library::messages::sensor)
# Image (horus_library::messages::vision)

Show message definition:

horus msg info CmdVel
# Output:
# struct CmdVel {
#   stamp_nanos: u64,  // nanoseconds
#   linear: f32,       // m/s forward velocity
#   angular: f32,      // rad/s turning velocity
# }

horus launch - Launch Multiple Nodes

What it does: Launch multiple nodes from a YAML configuration file.

Why it's useful: Start complex multi-node systems with one command, define node dependencies and parameters.

Basic Usage

# Launch from file
horus launch robot.yaml

# Preview without launching
horus launch robot.yaml --dry-run

# Launch with namespace
horus launch robot.yaml --namespace robot1

All Options

horus launch [OPTIONS] <FILE>

Arguments:
  <FILE>  Path to launch file (YAML)

Options:
  -n, --dry-run                Show what would launch without actually launching
      --namespace <NAMESPACE>  Namespace prefix for all nodes
      --list                   List nodes in the launch file without launching
  -h, --help                   Print help

Launch File Format

# robot.yaml
nodes:
  - name: sensor_node
    file: src/sensor.rs
    rate: 100
    params:
      sample_rate: 100

  - name: controller
    file: src/controller.rs
    rate: 50
    depends_on: [sensor_node]
    params:
      kp: 1.5
      ki: 0.1

  - name: logger
    file: src/logger.py
    rate: 10

Examples

Launch robot system:

horus launch robot.yaml

Launch with namespace (for multi-robot):

horus launch robot.yaml --namespace robot1
horus launch robot.yaml --namespace robot2

horus deploy - Deploy to Remote Robot(s)

What it does: Cross-compile and deploy your project to one or more remote robots over SSH. Supports named targets from deploy.yaml, fleet deployment to multiple robots, and parallel sync.

Why it's useful: Deploy from development machine to embedded robots. Build once, sync to many. Supports Raspberry Pi, Jetson, and any Linux target.

Basic Usage

# Deploy to a host directly
horus deploy pi@192.168.1.100

# Deploy to a named target from deploy.yaml
horus deploy jetson-01

# Deploy and run immediately
horus deploy jetson-01 --run

# Deploy to multiple robots
horus deploy jetson-01 jetson-02 jetson-03

# Deploy to ALL configured targets
horus deploy --all

# List configured targets
horus deploy --list

All Options

horus deploy [OPTIONS] [TARGETS]...

Arguments:
  [TARGETS]...  Target(s) — named targets from deploy.yaml or direct user@host

Options:
      --all                  Deploy to ALL targets in deploy.yaml
      --parallel             Deploy to multiple targets in parallel
  -d, --dir <REMOTE_DIR>     Remote directory (default: ~/horus_deploy)
  -a, --arch <ARCH>          Target architecture (aarch64, armv7, x86_64, native)
      --run                  Run the project after deploying
      --debug                Build in debug mode instead of release
  -p, --port <PORT>          SSH port (default: 22)
  -i, --identity <IDENTITY>  SSH identity file
  -n, --dry-run              Show what would be done without doing it
      --list                 List configured deployment targets

Fleet Deployment

Deploy to multiple robots at once. The build runs once (shared across targets with the same architecture), then syncs to each robot:

# Sequential (default) — deploys one at a time
horus deploy jetson-01 jetson-02 jetson-03

# All targets from deploy.yaml
horus deploy --all

# Dry run to preview fleet deployment
horus deploy --all --dry-run

Configure Named Targets

Create deploy.yaml in your project root:

targets:
  jetson-01:
    host: nvidia@10.0.0.1
    arch: aarch64
    dir: ~/robot
  jetson-02:
    host: nvidia@10.0.0.2
    arch: aarch64
    dir: ~/robot
  arm-controller:
    host: pi@10.0.0.10
    arch: aarch64
    dir: ~/arm
    port: 2222
    identity: ~/.ssh/robot_key

Then deploy by name:

horus deploy jetson-01              # single target
horus deploy jetson-01 jetson-02    # multiple targets
horus deploy --all                  # all targets
horus deploy --list                 # show all configured targets

Examples

Deploy to Raspberry Pi:

horus deploy pi@raspberrypi.local --arch aarch64

Deploy and run on NVIDIA Jetson:

horus deploy ubuntu@jetson.local --arch aarch64 --run

Deploy entire warehouse fleet:

horus deploy --all --dry-run   # preview first
horus deploy --all             # deploy to all robots

Then deploy with:

horus deploy jetson --run

horus add - Add Dependency

What it does: Adds a dependency to horus.toml. Auto-detects the source (crates.io, PyPI, system) based on your project language. Like cargo add — for project dependencies that get built with your code.

Why it's useful: Single command to add dependencies from any ecosystem — Rust, Python, system packages, or the horus registry. For standalone tools and plugins, use horus install instead.

Basic Usage

# Auto-detects source from project language
horus add serde                          # Rust project → crates.io
horus add numpy                          # Python project → PyPI

# Explicit source override
horus add serde --source crates-io
horus add numpy --source pypi
horus add libudev --source system
horus add horus-nav-stack --source registry

# With version and features
horus add serde@1.0 --features derive

# Add to dev-dependencies
horus add criterion --dev

# Add as driver
horus add camera-driver --driver

Source Auto-Detection

Project Typehorus add foo defaults to
Rust onlycrates.io
Python onlyPyPI
Multi-languageChecks known package tables, then project context
C++ onlysystem

Override with --source: crates-io, pypi, system, registry, git, path


horus install - Install Standalone Package

What it does: Installs a standalone package or plugin from the horus registry to ~/.horus/cache/. Like cargo install — for tools and plugins that aren't project dependencies.

Why it's useful: Install prebuilt drivers, plugins, and CLI extensions that work across all your projects. Does NOT modify horus.toml — use horus add for project dependencies.

horus add vs horus install

CommandLikePurposeModifies horus.toml?
horus add serdecargo addAdd project dependencyYes
horus install slam-toolboxcargo installInstall standalone tool/pluginNo

Basic Usage

horus install horus-sim3d              # Install a plugin
horus install rplidar-driver@1.2.0     # Install specific version
horus install horus-visualizer --plugin  # Install as CLI plugin

horus remove - Remove Dependency

What it does: Removes a dependency from horus.toml.

Why it's useful: Clean up unused dependencies from your project.

Basic Usage

horus remove pid-controller

# Remove and purge unused dependencies
horus remove sensor-fusion --purge

# Remove global package
horus remove common-utils --global

All Options

horus remove [OPTIONS] <NAME>

Arguments:
  <NAME>  Package/driver/plugin name to remove

Options:
  -g, --global   Remove from global scope
      --purge    Also remove unused dependencies
  -h, --help     Print help

horus plugin - Plugin Management

Alias: horus plugins

What it does: Manage HORUS plugins (extensions that add CLI commands or features). Plugins are installed via horus install --plugin and managed with the plugin subcommands.

Why it's useful: Enable/disable plugins without uninstalling, verify plugin integrity after updates.

Subcommands

horus plugin enable <command>        # Enable a disabled plugin
horus plugin disable <command>       # Disable a plugin (keep installed but don't execute)
horus plugin verify [plugin]         # Verify integrity of installed plugins

All Options

SubcommandFlagDescription
disable--reason <TEXT>Reason for disabling (recorded in config)
verify--jsonOutput as JSON

Examples

Enable a plugin:

horus plugin enable horus-visualizer

Disable a plugin temporarily:

horus plugin disable horus-visualizer --reason "debugging"

Verify all plugins:

horus plugin verify

Verify a specific plugin:

horus plugin verify horus-visualizer --json

Install and manage a plugin end-to-end:

horus search visualizer              # Find plugins
horus install horus-visualizer --plugin  # Install as plugin
horus plugin disable horus-visualizer    # Disable temporarily
horus plugin enable horus-visualizer     # Re-enable
horus plugin verify horus-visualizer     # Verify integrity

horus cache - Cache Management

What it does: Manage the HORUS package cache (downloaded packages, compiled artifacts).

Why it's useful: Reclaim disk space, troubleshoot package issues.

Subcommands

horus cache info               # Show cache statistics (size, package count)
horus cache list               # List all cached packages
horus cache clean              # Remove unused packages (--dry-run to preview)
horus cache purge              # Remove ALL cached packages (-y to skip confirmation)

Examples

Check cache usage:

horus cache info
# Output:
# Location: ~/.horus/cache
# Total size: 1.2 GB
# Packages: 45
# Last cleaned: 7 days ago

Clean unused packages:

horus cache clean
# Removes packages not used by any project

horus record - Record/Replay Management

What it does: Manage recorded sessions for debugging and testing.

Why it's useful: Replay exact scenarios, compare runs, debug timing-sensitive issues.

Subcommands

horus record list              # List all recordings
horus record info <session>    # Show recording details
horus record replay <session>  # Replay a recording
horus record delete <session>  # Delete a recording
horus record diff <a> <b>      # Compare two recordings
horus record export <session>  # Export to different format
horus record inject <session>  # Inject recorded data into live scheduler

Examples

List recordings:

horus record list
# Output:
# ID         DATE                 DURATION   NODES   SIZE
# rec_001    2024-01-15 10:30:00  5m 23s     4       45MB
# rec_002    2024-01-15 14:15:00  2m 10s     3       18MB

Replay a session:

horus record replay rec_001

Compare two runs:

horus record diff rec_001 rec_002
# Shows differences in timing, message counts, errors

Inject recorded data into live system:

# Use recorded sensor data with live controller
horus record inject rec_001 --nodes SensorNode

horus blackbox - BlackBox Flight Recorder

Alias: horus bb

What it does: Inspects the BlackBox flight recorder for post-mortem crash analysis. The BlackBox automatically records scheduler events, errors, deadline misses, and safety state changes.

Why it's useful: After a crash or anomaly, review exactly what happened — which nodes failed, when deadlines were missed, and what the safety state was at each tick.

Basic Usage

# View all recorded events
horus blackbox

# Show only anomalies (errors, deadline misses, WCET violations, e-stops)
horus blackbox --anomalies

# Follow mode — stream events in real-time (like tail -f)
horus blackbox --follow

All Options

horus blackbox [OPTIONS]

Options:
  -a, --anomalies          Show only anomalies (errors, deadline misses,
                           WCET violations, e-stops)
  -f, --follow             Follow mode — stream new events as they arrive
  -t, --tick <RANGE>       Filter by tick range (e.g. "4500-4510" or "4500")
  -n, --node <NAME>        Filter by node name (partial, case-insensitive)
  -e, --event <TYPE>       Filter by event type (e.g. "DeadlineMiss", "NodeError")
      --json               Output as machine-readable JSON
  -l, --last <N>           Show only the last N events
  -p, --path <DIR>         Custom blackbox directory (default: .horus/blackbox/)
      --clear              Clear all blackbox data (with confirmation)

Examples

View recent anomalies:

horus bb --anomalies --last 20

Filter by node and tick range:

horus bb --node controller --tick 4500-4510

Stream events in real-time while debugging:

horus bb --follow --anomalies

Export to JSON for external analysis:

horus bb --json > blackbox_dump.json

Clear old data:

horus bb --clear

horus fmt - Format Code

What it does: Formats your project's source code using language-appropriate tools (Rust via rustfmt, Python via ruff/black).

Why it's useful: Enforce consistent code style across your project without manual formatting. Use --check in CI to fail on unformatted code.

Basic Usage

# Format all code in the project
horus fmt

# Check formatting without modifying files (useful for CI)
horus fmt --check

All Options

horus fmt [OPTIONS] [-- EXTRA_ARGS]

Options:
      --check          Check formatting without modifying files
  -- <EXTRA_ARGS>      Additional arguments passed to underlying tools

Options:

FlagDescription
--checkCheck formatting without modifying files (exit code 1 if unformatted)
-- <ARGS>Additional arguments passed to rustfmt or ruff format

Examples

Format before committing:

horus fmt
git add -A && git commit -m "formatted"

CI formatting check:

horus fmt --check || (echo "Run 'horus fmt' to fix formatting" && exit 1)

Pass extra arguments to rustfmt:

horus fmt -- --edition 2021

horus lint - Lint Code

What it does: Runs linters on your project (Rust via clippy, Python via ruff/pylint). Optionally runs type checking for Python.

Why it's useful: Catch bugs, anti-patterns, and style issues before they reach production.

Basic Usage

# Lint all code
horus lint

# Auto-fix lint issues where possible
horus lint --fix

# Also run Python type checker (mypy/pyright)
horus lint --types

All Options

horus lint [OPTIONS] [-- EXTRA_ARGS]

Options:
      --fix            Auto-fix lint issues where possible
      --types          Also run Python type checker (mypy/pyright)
  -- <EXTRA_ARGS>      Additional arguments passed to underlying tools

Options:

FlagDescription
--fixAuto-fix lint issues where possible
--typesAlso run Python type checker (mypy/pyright)
-- <ARGS>Additional arguments passed to clippy or ruff check

Examples

Lint and auto-fix:

horus lint --fix

Full lint with type checking:

horus lint --types

CI lint gate:

horus lint || exit 1

horus doc - Generate Documentation

What it does: Generates documentation for your project. Supports multiple output formats (JSON, Markdown, HTML), doc coverage reporting, API extraction, and topic/message flow graphs.

Why it's useful: Generate API docs, measure documentation coverage, extract machine-readable API data for tooling, and enforce minimum coverage in CI.

Basic Usage

# Generate docs and open in browser
horus doc --open

# Show documentation coverage report
horus doc --coverage

# Extract machine-readable API documentation as JSON
horus doc --extract --json

All Options

horus doc [OPTIONS] [-- EXTRA_ARGS]

Options:
      --open                   Open documentation in browser after generating
      --extract                Extract machine-readable API documentation
      --json                   Output as JSON
      --md                     Output as markdown (for LLM context)
      --html                   Output as self-contained HTML report
      --full                   Include doc comments in brief output
      --all                    Include private/crate-only symbols
      --lang <LANG>            Filter by language (rust, python)
      --coverage               Show documentation coverage report
  -o, --output <FILE>          Write output to file instead of stdout
      --diff <BASELINE>        Compare against a baseline JSON file
      --fail-under <PERCENT>   Fail if doc coverage is below this percentage (for CI)
      --watch                  Watch for file changes and regenerate
  -- <EXTRA_ARGS>              Additional arguments passed to underlying tools

Options:

FlagDescription
--openOpen documentation in browser after generating
--extractExtract machine-readable API documentation
--jsonOutput as JSON
--mdOutput as markdown (useful for LLM context)
--htmlOutput as self-contained HTML report
--fullInclude doc comments in brief output
--allInclude private/crate-only symbols
--lang <LANG>Filter by language (rust, python)
--coverageShow documentation coverage report
-o, --output <FILE>Write output to file instead of stdout
--diff <BASELINE>Compare against a baseline JSON file
--fail-under <PERCENT>Fail if doc coverage is below this percentage (for CI)
--watchWatch for file changes and regenerate

Examples

Generate and browse docs:

horus doc --open

CI documentation coverage gate:

horus doc --coverage --fail-under 80

Extract API docs as markdown for LLM context:

horus doc --extract --md -o api.md

Track API changes between releases:

horus doc --extract --json -o api-v2.json
horus doc --diff api-v1.json

Watch mode during development:

horus doc --watch --open

horus bench - Run Benchmarks

What it does: Runs benchmarks for your HORUS project. Supports filtering by name and passing extra arguments to the underlying benchmark framework.

Why it's useful: Measure and track performance of your nodes, algorithms, and IPC throughput.

Basic Usage

# Run all benchmarks
horus bench

# Run benchmarks matching a filter
horus bench latency

All Options

horus bench [OPTIONS] [FILTER] [-- EXTRA_ARGS]

Arguments:
  [FILTER]         Filter benchmarks by name

Options:
  -- <EXTRA_ARGS>  Additional arguments passed to underlying tools

Options:

FlagDescription
[FILTER]Filter benchmarks by name (substring match)
-- <ARGS>Additional arguments passed to the benchmark runner

Examples

Run all benchmarks:

horus bench

Run specific benchmarks:

horus bench ipc_throughput

Pass extra arguments to criterion:

horus bench -- --sample-size 100

horus deps - Dependency Insight

What it does: Inspect, audit, and manage your project's dependencies. Provides subcommands for viewing the dependency tree, explaining why a package is included, checking for outdated packages, and running security audits.

Why it's useful: Understand your dependency graph, find unused or outdated packages, and catch known vulnerabilities.

Subcommands

horus deps tree                  # Show dependency tree
horus deps why <package>         # Explain why a dependency is included
horus deps outdated              # Check for outdated dependencies
horus deps audit                 # Security audit of dependencies

Examples

View dependency tree:

horus deps tree

Find out why a package is included:

horus deps why serde
# Output: serde is required by:
#   horus_core -> serde (serialize node configs)
#   horus_library -> serde (message serialization)

Check for outdated dependencies:

horus deps outdated

Run security audit:

horus deps audit
# Checks against RustSec advisory database

Pass extra arguments to underlying tools:

horus deps tree -- --depth 2

horus doctor - Health Check

What it does: Runs a comprehensive health check of your HORUS ecosystem, including toolchain versions, configuration validity, system dependencies, and environment setup. With --fix, installs missing toolchains and system dependencies automatically.

Why it's useful: Quickly diagnose setup issues, verify that all required tools are installed, and ensure your environment is ready for development. New contributors can run horus doctor --fix to get a working environment in one command.

Basic Usage

# Run health check
horus doctor

# Install missing toolchains and system dependencies
horus doctor --fix

# Verbose output with detailed check results
horus doctor --verbose

# Output as JSON (for tooling)
horus doctor --json

All Options

horus doctor [OPTIONS]

Options:
  -v, --verbose    Show detailed output for each check
      --json       Output as JSON
      --fix        Install missing toolchains and system dependencies
FlagDescription
-v, --verboseShow detailed output for each check
--jsonOutput as JSON
--fixInstall missing toolchains and system deps, pin versions to horus.lock

What It Checks

CheckDescription
Toolchainscargo, rustc, python3, ruff, pytest, cmake, clang-format, clang-tidy
Manifesthorus.toml validity and structure
Shared MemorySHM directory exists and is accessible
PluginsGlobal and local plugin counts
DiskBuild cache size (.horus/ directory)
LanguagesDetected project languages (Rust, Python, C++)
DependenciesDependency source validation
DriversDevice reachability (serial ports, I2C buses, network endpoints)
System DepsPython version, C++ compiler, system libraries from horus.toml

Examples

Quick health check:

horus doctor
# horus doctor
#
#   ✓ Toolchains — 6/8 tools found
#   ✓ Manifest — horus.toml valid
#   ✓ Shared Memory — /dev/shm available
#   ✓ Plugins — 2 global, 0 local
#   ✓ Disk — Build cache uses 148.3 MB
#   ✓ Languages — Rust, Python
#   ✓ Dependencies — 12 deps, sources look correct
#   ✓ Drivers — 3 driver(s) reachable
#   ✗ System Deps — 2/3 satisfied — run horus doctor --fix to install

Fix missing dependencies:

horus doctor --fix
# Runs all checks, then installs missing toolchains and system packages.
# Pins installed versions to horus.lock [toolchain] and [[system]] sections.

Driver reachability (checks [drivers] entries from horus.toml):

horus doctor --verbose
# ...
# ✓ Drivers — 3 driver(s) checked, some unreachable
#     ✓ driver 'imu': /dev/i2c-1 found
#     ✗ driver 'arm': /dev/ttyUSB0 not found
#     ! driver 'lidar': 192.168.1.201:2368 unreachable

Checks serial ports (Path::exists), I2C buses (/dev/i2c-N), and network endpoints (TcpStream with 2s timeout). No terra dependency — pure OS-level checks.

CI environment validation:

horus doctor --json | jq '.[] | select(.health != "ok")'

horus self update - Update CLI

What it does: Updates the horus CLI binary to the latest version. Like rustup self update.

Why it's useful: Keep your CLI current without affecting project dependencies (use horus update for deps).

Migration: horus upgrade still works but is deprecated. Use horus self update instead.

Basic Usage

# Update the CLI binary
horus self update

# Check for updates without installing
horus self update --check

Options

FlagDescription
--checkCheck for available updates without installing

Examples

Check if update is available:

horus self update --check
# Output: Current: 0.1.9, Latest: 0.2.0 — update available

Update the CLI:

horus self update

Update project dependencies separately:

horus update          # Update deps in horus.toml
horus self update     # Update CLI binary

horus config - Config Management

What it does: View and edit horus.toml settings from the command line using dot-notation keys.

Why it's useful: Quickly inspect or modify project configuration without opening an editor. Useful for scripting and CI.

Subcommands

horus config get <key>           # Get a config value
horus config set <key> <value>   # Set a config value
horus config list                # List all config values

Examples

Get a config value:

horus config get package.name
# Output: my_robot

Set a config value:

horus config set package.version "0.2.0"

List all config values:

horus config list
# Output:
# package.name = "my_robot"
# package.version = "0.1.0"
# package.language = "rust"

horus migrate - Migrate to horus.toml

What it does: Migrates an existing project to the unified horus.toml format. Detects existing Cargo.toml, pyproject.toml, or package.xml files and consolidates them into a single horus.toml manifest.

Why it's useful: Move legacy projects to the unified HORUS manifest format. The --dry-run flag lets you preview changes before committing.

Basic Usage

# Migrate (interactive, asks for confirmation)
horus migrate

# Preview what would change
horus migrate --dry-run

# Skip confirmation prompts
horus migrate --force

All Options

horus migrate [OPTIONS]

Options:
  -n, --dry-run    Show what would change without modifying
  -f, --force      Skip confirmation prompts

Options:

FlagDescription
-n, --dry-runShow what would change without modifying
-f, --forceSkip confirmation prompts

Examples

Preview migration:

horus migrate --dry-run
# Output:
# Would create: horus.toml
# Would move: Cargo.toml -> .horus/Cargo.toml
# Would extract: 5 dependencies from Cargo.toml

Migrate existing Rust project:

cd my-existing-project
horus migrate --force
# horus.toml created, Cargo.toml moved to .horus/

horus scripts - Run Scripts

Alias: horus script

What it does: Runs a named script defined in the [scripts] section of horus.toml. If no script name is given, lists all available scripts.

Why it's useful: Define project-specific commands (test suites, deployment steps, data processing) in horus.toml and run them with a single command.

Basic Usage

# List available scripts
horus scripts

# Run a script by name
horus scripts deploy

# Run a script with arguments
horus scripts test -- --verbose

All Options

horus scripts [NAME] [-- ARGS]

Arguments:
  [NAME]       Script name to run (omit to list available scripts)
  -- <ARGS>    Arguments to pass to the script

Examples

Define scripts in horus.toml:

[scripts]
deploy = "rsync -avz ./target/release/ robot@192.168.1.100:~/app/"
test-hw = "horus test --integration --sim"
bench = "horus bench -- --sample-size 50"

List scripts:

horus scripts
# Output:
# deploy    rsync -avz ./target/release/ robot@192.168.1.100:~/app/
# test-hw   horus test --integration --sim
# bench     horus bench -- --sample-size 50

Run a script:

horus scripts deploy

horus env - Shell Integration

What it does: Manages shell integration for HORUS, setting up proxy wrappers so that cargo, pip, and cmake invocations inside a HORUS project automatically use the correct .horus/ build directory and dependencies.

Why it's useful: Lets native tools (cargo, pip, cmake) work seamlessly with horus.toml projects without manual configuration.

Basic Usage

# Print shell integration script to stdout
horus env

# Install shell integration (sets up cargo/pip/cmake proxy)
horus env --init

# Remove shell integration
horus env --uninstall

All Options

horus env [OPTIONS]

Options:
      --init               Install shell integration (cargo/pip/cmake proxy)
      --uninstall          Remove shell integration

How It Works

Running horus env --init adds shell functions that intercept calls to cargo, pip, and cmake. When you run cargo build inside a HORUS project directory, the proxy detects the horus.toml, redirects to the generated .horus/Cargo.toml, and passes the build through the HORUS pipeline. Outside of HORUS projects, the native tools behave normally.

To activate for the current shell session without permanent installation:

eval "$(horus env)"

To make it permanent, horus env --init appends the integration to your shell profile (~/.bashrc, ~/.zshrc, etc.).

Examples

One-time setup (recommended):

horus env --init
# Restart your shell or source your profile
source ~/.bashrc

Verify integration is active:

horus env
# Prints the shell functions; if already sourced, cargo/pip are proxied

Remove if no longer needed:

horus env --uninstall
source ~/.bashrc

For a detailed walkthrough of how native tool integration works, see Native Tool Integration.


horus completion - Shell Completions

What it does: Generates shell completion scripts for bash, zsh, fish, elvish, or PowerShell. This is a hidden command (not shown in horus --help).

Why it's useful: Get tab-completion for all horus commands and flags in your shell.

Basic Usage

# Bash
horus completion bash > ~/.local/share/bash-completion/completions/horus

# Zsh
horus completion zsh > ~/.zfunc/_horus

# Fish
horus completion fish > ~/.config/fish/completions/horus.fish

Supported Shells

ShellValue
Bashbash
Zshzsh
Fishfish
Elvishelvish
PowerShellpowershell

Common Workflows

First Time Using HORUS

# Create a project
horus new my_robot --rust
cd my_robot

# Run it
horus run

# Monitor it (open a second terminal)
horus monitor

Daily Development Cycle

# Edit your code
vim src/main.rs

# Format + lint before running
horus fmt
horus lint

# Run and test
horus run
horus test

# Monitor in another terminal
horus monitor

Debugging a Motor Stutter

Your robot's motor is stuttering. Here's how to diagnose with the CLI:

# Step 1: Run with monitoring
horus run --release

# Step 2: Watch the motor command topic (another terminal)
horus topic echo motor/cmd_vel

# Step 3: Check if the motor node is missing deadlines
horus node info motor_ctrl
# Look at: avg_tick_ms, max_tick_ms, deadline_misses

# Step 4: Check the blackbox for deadline miss events
horus blackbox --follow

# Step 5: Record a session for offline analysis
horus record start
# ... reproduce the stutter ...
horus record stop

# Step 6: Replay the session to reproduce
horus record replay --session latest

Adding a New Sensor

You're adding a LiDAR to your robot:

# Step 1: Check if there's a driver package available
horus search rplidar
horus install rplidar

# Step 2: If not, create your own driver
horus new lidar_driver --rust
cd lidar_driver
# ... write your driver code ...

# Step 3: Run and verify data flow
horus run

# In another terminal:
horus topic list                    # See all topics
horus topic echo lidar/scan         # Watch scan data
horus topic hz lidar/scan           # Check publish rate

# Step 4: Verify coordinate frames
horus tf tree                       # See frame hierarchy
horus tf echo lidar base_link       # Check transform

Preparing for Field Deployment

Pre-deployment checklist using the CLI:

# Step 1: Validate everything
horus doctor                        # Ecosystem health check
horus check                         # Validate horus.toml
horus fmt --check                   # Ensure code is formatted
horus lint                          # Check for issues

# Step 2: Run tests
horus test
horus bench                         # Check performance hasn't regressed

# Step 3: Check dependencies
horus deps outdated                 # Find outdated deps
horus deps audit                    # Security audit

# Step 4: Clean build and verify
horus run --clean --release

# Step 5: Deploy to robot
horus deploy robot@192.168.1.10 --release

Multi-Robot Development

Working with multiple robots that share code:

# Step 1: Publish shared packages
cd common_messages
horus publish

cd ../lidar_driver
horus publish

# Step 2: Install on each robot project
cd robot_alpha
horus install common_messages lidar_driver

cd ../robot_beta
horus install common_messages lidar_driver

# Step 3: Check running nodes
horus node list

CI/CD Pipeline

# In your CI config (GitHub Actions, GitLab CI, etc.):
horus fmt --check                   # Fail if unformatted
horus lint                          # Fail on lint errors
horus check                         # Validate project
horus test                          # Run all tests
horus bench --fail-under 0.95       # Performance gate (optional)
horus doc --coverage --fail-under 80 # Doc coverage gate (optional)

Share Your Work

# Login once
horus auth login

# Publish
horus publish

# Others can now:
horus install your-package-name

Troubleshooting

"command not found: horus"

Add cargo to your PATH:

export PATH="$HOME/.cargo/bin:$PATH"
echo 'export PATH="$HOME/.cargo/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

"Port already in use"

# Use different port
horus monitor 3001

# Or kill the old process
lsof -ti:3000 | xargs kill -9

Build is slow

First build is always slow (5-10 min). After that it's fast (seconds).

Use --release only when you need speed, not during development.

"Failed to create Topic"

Topic name conflict. Try a unique name or clean up stale shared memory.

Note: HORUS automatically cleans up shared memory after each run using session isolation. This error usually means a previous run crashed.

# Clean all HORUS shared memory (if needed after crashes)
horus clean --shm

Environment Variables

Optional configuration:

# Custom registry (for companies)
export HORUS_REGISTRY_URL=https://your-company-registry.com

# Debug mode (see what's happening)
export RUST_LOG=debug
horus run

# CI/CD authentication
export HORUS_API_KEY=your-key-here

Utility Scripts

Beyond the horus CLI, the repository includes helpful scripts:

./install.sh             # Install or update HORUS

See Troubleshooting & Maintenance for complete details.


Next Steps

Now that you know the commands:

  1. Quick Start - Build your first app
  2. node! Macro - Write less code
  3. Monitor Guide - Master monitoring
  4. Examples - See real applications

Having issues? Check the Troubleshooting Guide for solutions to common problems.