Configuration Reference
Complete guide to configuring HORUS projects via horus.toml and understanding the auto-managed .horus/ directory.
Quick Reference
Minimal horus.toml:
[package]
name = "my_robot"
version = "0.1.0"
Full horus.toml:
[package]
name = "my_robot_controller"
version = "1.2.3"
description = "Advanced mobile robot controller with navigation"
authors = ["Robotics Team <team@example.com>"]
license = "Apache-2.0"
edition = "1"
repository = "https://github.com/team/my-robot-controller"
package-type = "app"
categories = ["control", "navigation"]
[drivers]
camera = "opencv"
lidar = true
enable = ["cuda", "editor"]
[ignore]
files = ["debug_*.rs", "**/temp/**"]
directories = ["experiments/", "old/"]
packages = ["ipython"]
Project Metadata
All project metadata fields live under the [package] table. horus.toml is a config-only manifest -- it does not contain dependencies or language settings. Dependencies live in native build files (Cargo.toml for Rust, pyproject.toml for Python), and language is auto-detected from which build files exist.
name (Required)
Project name used for identification and package management.
Type: String Required: Yes Constraints:
- Must be unique within your organization
- Use lowercase with hyphens (kebab-case)
- No spaces or special characters except hyphens and underscores
Examples:
[package]
name = "temperature-monitor"
# or
name = "mobile_robot_controller"
# or
name = "warehouse-navigation"
version (Required)
Project version following semantic versioning.
Type: String
Required: Yes
Format: MAJOR.MINOR.PATCH (semantic versioning)
Examples:
[package]
version = "0.1.0" # Initial development
# or
version = "1.0.0" # First stable release
# or
version = "2.3.1" # Mature project
edition (Optional)
Manifest schema version. Controls which fields and features are available in horus.toml.
Type: String
Required: No
Default: "1"
Examples:
[package]
edition = "1"
description (Optional)
Human-readable description of your project.
Type: String Required: No Default: None
Examples:
[package]
description = "Temperature monitoring system with alerts"
# or
description = "Autonomous mobile robot for warehouse operations"
authors (Optional)
Project authors list.
Type: Array of strings Required: No Default: None
Examples:
[package]
authors = ["Robotics Team <team@example.com>"]
# or
authors = ["John Doe <john@example.com>", "Jane Smith <jane@example.com>"]
license (Optional)
Project license identifier.
Type: String
Required: No
Default: None
Common Values: Apache-2.0, MIT, GPL-3.0, BSD-3-Clause
Examples:
[package]
license = "Apache-2.0"
# or
license = "MIT"
# or
license = "Proprietary"
repository (Optional)
URL to the project's source repository.
Type: String Required: No Default: None
Examples:
[package]
repository = "https://github.com/team/my-robot"
package-type (Optional)
Classification of the package for registry discovery.
Type: String
Required: No
Default: None
Values: node, driver, tool, algorithm, model, message, app
Examples:
[package]
package-type = "app"
# or
package-type = "node"
# or
package-type = "driver"
categories (Optional)
Categories for package discovery in the registry.
Type: Array of strings Required: No Default: None
Examples:
[package]
categories = ["control", "navigation", "perception"]
Language Auto-Detection
HORUS automatically detects the project language from native build files present in the project directory:
| Build File | Detected Language |
|---|---|
Cargo.toml | Rust |
pyproject.toml | Python |
No language field is needed in horus.toml. When you run horus new, both horus.toml and the appropriate native build file (Cargo.toml or pyproject.toml) are created.
Dependencies
Dependencies are managed through native build files, not through horus.toml:
| Language | Build File | Add Dependencies With |
|---|---|---|
| Rust | Cargo.toml | horus add <crate> (delegates to cargo add) |
| Python | pyproject.toml | horus add <package> (delegates to pip install) |
HORUS registry packages are also added with horus add, which updates the appropriate native build file.
Rust Dependencies (Cargo.toml)
For Rust projects, dependencies live in Cargo.toml alongside your horus.toml:
# Cargo.toml (managed by cargo / horus add)
[package]
name = "my-robot"
version = "0.1.0"
edition = "2021"
[dependencies]
horus = { path = "..." }
serde = { version = "1", features = ["derive"] }
tokio = { version = "1", features = ["full"] }
Adding dependencies:
# Add a crate (delegates to cargo add)
horus add serde --features derive
horus add tokio --features full
# Add from HORUS registry
horus add pid-controller
# Add with specific version
horus add serde@1.0.200
Python Dependencies (pyproject.toml)
For Python projects, dependencies live in pyproject.toml:
# pyproject.toml
[project]
name = "my-robot"
version = "0.1.0"
dependencies = [
"horus-robotics",
"numpy>=1.24",
"opencv-python>=4.8",
]
Adding dependencies:
# Add a package (delegates to pip install)
horus add numpy
horus add opencv-python
# Add from HORUS registry
horus add pid-controller
HORUS Registry Packages
HORUS registry packages (horus add <name>) are added to the appropriate native build file based on the detected project language.
# Install from HORUS registry
horus add pid-controller
horus add sensor-fusion
horus add motion-planner
Ignore Patterns
ignore (Optional)
Exclude files and directories from HORUS processing.
Type: Table with optional files and directories arrays
Required: No
Default: None
ignore.files
Exclude specific files from detection and execution.
Type: Array of glob patterns
Patterns: * (wildcard), **/ (recursive directories)
Examples:
[ignore]
files = [
"debug_*.py", # Ignore debug_test.py, debug_node.py
"test_*.rs", # Ignore all test files
"**/experiments/**", # Ignore files in any experiments/ directory
"scratch.rs", # Ignore specific file
]
ignore.directories
Exclude entire directories.
Type: Array of directory names or paths
Examples:
[ignore]
directories = ["old/", "experiments/", "tests/", "benchmarks/"]
ignore.packages
Skip specific packages during auto-install.
Type: Array of package name strings
Examples:
[ignore]
packages = ["ipython", "debugpy"]
Complete Ignore Example
[package]
name = "robot_controller"
version = "0.1.0"
[ignore]
# Don't run debug files
files = ["debug_*.py", "test_*.rs", "**/temp/**"]
# Don't process these directories
directories = ["old_controllers/", "experiments/", "docs/"]
Feature Flags
enable (Optional)
Enable optional feature flags for your project.
Type: Array of strings (at the top level, outside any table)
Examples:
enable = ["cuda", "editor"]
Hooks
[hooks] (Optional)
Declare commands that run automatically before or after horus run, horus build, and horus test. Eliminates manual horus fmt && horus lint && horus run pipelines.
Fields:
| Field | Type | Description |
|---|---|---|
pre_run | string[] | Run before horus run |
pre_build | string[] | Run before horus build |
pre_test | string[] | Run before horus test |
post_test | string[] | Run after horus test |
Built-in hook names: fmt, lint, check. Any other name is looked up in [scripts].
Example:
[hooks]
pre_run = ["fmt", "lint"] # Auto-format and lint before every run
pre_test = ["lint"] # Lint before testing
post_test = ["clean --shm"] # Clean shared memory after tests (if defined in [scripts])
Skipping hooks:
horus run --no-hooks # Skip all hooks for this run
horus test --no-hooks # Skip hooks for this test
How it works: When you run horus run, the scheduler checks [hooks].pre_run. For each entry, it calls the corresponding command function (fmt → horus fmt, lint → horus lint). If any hook fails, the run is aborted. Use --no-hooks to bypass when debugging.
Driver Configuration
[drivers] (Optional)
Configure hardware drivers. Three forms supported:
Simple — enable a driver or specify a backend (feature flags only):
[drivers]
camera = "opencv"
lidar = true
Terra — connect to hardware via the Terra HAL. Auto-adds the correct Terra crate to your build:
[drivers.arm]
terra = "dynamixel"
port = "/dev/ttyUSB0"
baudrate = 1000000
servo_ids = [1, 2, 3, 4, 5, 6]
[drivers.lidar]
terra = "rplidar"
port = "/dev/ttyUSB1"
[drivers.imu]
terra = "bno055"
bus = "i2c-1"
address = 0x28
Registry package — use a community or vendor driver package:
[drivers.force_sensor]
package = "horus-driver-ati-netft"
address = "192.168.1.100"
filter_hz = 500
Local code — reference your own driver registered via register_driver!:
[drivers.conveyor]
node = "ConveyorDriver"
port = "/dev/ttyACM0"
baudrate = 57600
All forms can be mixed in the same file. The terra, package, and node keys determine the driver source. All other keys become params passed to the driver at runtime.
Supported Terra drivers:
| Name | Crate | Hardware |
|---|---|---|
dynamixel | terra-serial | Dynamixel servos |
rplidar | terra-serial | SLAMTEC RPLiDAR |
vesc | terra-serial | VESC motor controllers |
modbus | terra-serial | Modbus RTU devices |
realsense | terra-realsense | Intel RealSense cameras |
webcam | terra-webcam | V4L2 cameras |
velodyne, ouster, livox | terra-lidar | 3D LiDAR |
mpu6050, bno055 | terra-embedded | I2C IMU sensors |
odrive, canopen | terra-can | CAN bus devices |
ethercat | terra-ethercat | EtherCAT servos/PLCs |
i2c, spi, serial, can, gpio, pwm | terra- | Raw bus access |
virtual | terra-virtual | Mock devices for testing |
See the Driver API reference for the runtime API.
The .horus/ Directory
The .horus/ directory is automatically managed by HORUS. You should never manually edit files inside it.
Structure
my_project/
├── horus.toml # Project config (edit this)
├── Cargo.toml # Rust dependencies (edit this)
├── main.rs # Your code (edit this)
└── .horus/ # Build cache (don't touch)
├── target/ # Build artifacts
└── packages/ # Cached registry packages
For Python projects:
my_project/
├── horus.toml # Project config (edit this)
├── pyproject.toml # Python dependencies (edit this)
├── main.py # Your code (edit this)
└── .horus/ # Build cache (don't touch)
└── packages/ # Cached registry packages
What's Inside .horus/
.horus/ is a build cache only:
target/ (Rust projects):
- Cargo build artifacts
- Can be large (ignore in git)
packages/:
- Cached HORUS registry packages
- Symlinks to global cache when possible
Git Configuration
Always add to .gitignore:
# HORUS build cache
.horus/
The horus new command automatically creates this .gitignore for you.
When .horus/ is Created
.horus/ is created automatically when you run:
horus runhorus installhorus build
You never need to create it manually.
Cleaning .horus/
Remove local environment:
rm -rf .horus/
Regenerate on next run:
horus run # Automatically recreates .horus/
Complete Examples
Rust Application
horus.toml:
[package]
name = "temperature-monitor"
version = "0.1.0"
description = "Simple temperature monitoring system"
authors = ["Robotics Team"]
license = "Apache-2.0"
[ignore]
files = ["debug_*.rs"]
Cargo.toml (alongside horus.toml):
[package]
name = "temperature-monitor"
version = "0.1.0"
edition = "2021"
[dependencies]
horus = { path = "..." }
serde = { version = "1", features = ["derive"] }
Rust Application with Drivers
horus.toml:
[package]
name = "robot-backend"
version = "1.0.0"
description = "Robot control backend with sensor processing"
authors = ["ACME Robotics"]
license = "Apache-2.0"
[drivers]
camera = "opencv"
lidar = true
enable = ["cuda"]
[ignore]
directories = ["tests/"]
Cargo.toml:
[package]
name = "robot-backend"
version = "1.0.0"
edition = "2021"
[dependencies]
horus = { path = "..." }
serde = { version = "1", features = ["derive"] }
tokio = { version = "1", features = ["full"] }
[dev-dependencies]
criterion = "0.5"
Note: HORUS uses a flat namespace (like ROS), so multiple processes automatically share topics when using the same topic names. No configuration needed!
Python Application
horus.toml:
[package]
name = "vision-processor"
version = "0.2.0"
description = "Computer vision processing node"
authors = ["Vision Team"]
license = "MIT"
[ignore]
directories = ["notebooks/", "experiments/"]
pyproject.toml (alongside horus.toml):
[project]
name = "vision-processor"
version = "0.2.0"
dependencies = [
"horus-robotics",
"numpy>=1.24",
"opencv-python>=4.8",
"pillow",
]
Best Practices
Version Your Configuration
Always commit horus.toml and your native build file to version control:
git add horus.toml Cargo.toml # Rust project
git add horus.toml pyproject.toml # Python project
Use Semantic Versioning
Follow semver for your project version:
0.x.y- Initial development1.0.0- First stable releasex.y.z- Major.Minor.Patch
Keep horus.toml Minimal
horus.toml is config only. Dependencies go in native build files:
# Good (minimal horus.toml)
[package]
name = "my_robot"
version = "0.1.0"
Add optional fields only when needed:
# With optional metadata
[package]
name = "my_robot"
version = "0.1.0"
description = "A temperature monitoring robot"
authors = ["Team"]
license = "MIT"
Validation
HORUS validates horus.toml on every command. Common errors:
Missing Required Fields
Error: Missing required field 'name' in horus.toml
Fix: Add name and version fields under [package].
Invalid TOML Syntax
Error: Failed to parse horus.toml: invalid TOML syntax at line 5
Fix: Check TOML syntax (key-value pairs use =, strings must be quoted, tables use [brackets]).
Invalid Version Format
Error: Invalid version format: '1.0'. Expected semantic version (e.g., '1.0.0')
Fix: Use format "MAJOR.MINOR.PATCH".
Next Steps
- Package Management - Install and manage packages
- CLI Reference - All HORUS commands
- Topic - Understanding the IPC architecture