Files
horus/bin/runners/hero

Hero Runner

A specialized runner for the Hero ecosystem that executes heroscripts using the hero CLI tool.

Overview

The Hero runner executes heroscripts by piping the payload to hero run -s via stdin for each job. This makes it ideal for:

  • Running heroscripts from job payloads
  • Executing Hero automation tasks (e.g., !!git.list, !!docker.start)
  • Integrating with the Hero CLI ecosystem
  • Running scripted workflows

Features

  • Heroscript Execution: Pipes payload to hero run -s via stdin (no temp files)
  • Environment Variables: Passes job environment variables to the hero command
  • Timeout Support: Respects job timeout settings
  • Signature Verification: Verifies job signatures before execution
  • Simple Integration: No complex payload parsing - just pass the heroscript content

Usage

Starting the Runner

# Basic usage
herorunner my-hero-runner

# With custom Redis URL
herorunner my-hero-runner --redis-url redis://localhost:6379

Command-line Options

  • runner_id: Runner identifier (required, positional)
  • -r, --redis-url: Redis URL (default: redis://localhost:6379)

Job Payload Format

The job payload should contain the heroscript content. The runner will pipe it directly to hero run -s via stdin.

Example Payloads

Simple print:

print("Hello from heroscript!")

Hero actions:

!!git.list

Multi-line script:

!!git.list
print("Repositories listed")
!!docker.ps

The runner executes: echo "<payload>" | hero run -s

Examples

Example 1: Simple Heroscript

Job payload:

print("Processing job...")

Executed as: hero run -h 'print("Processing job...")'

Example 2: Multi-line Heroscript

Job payload:

print("Starting task...")
// Your heroscript logic here
print("Task completed!")

Example 3: With Environment Variables

Job with env_vars:

{
  "payload": "print(env.MY_VAR)",
  "env_vars": {
    "MY_VAR": "Hello from Hero Runner"
  }
}

Architecture

The Hero runner implements the Runner trait from hero-runner library:

┌─────────────────────┐
│  HeroExecutor      │
│                     │
│  - execute_command()│
│  - process_job()    │
└─────────────────────┘
          │
          │ implements
          ▼
┌─────────────────────┐
│   Runner Trait      │
│                     │
│  - spawn()          │
│  - process_job()    │
│  - runner_type()    │
└─────────────────────┘
          │
          │ executes
          ▼
┌─────────────────────┐
│  hero run -h        │
│  <heroscript>       │
└─────────────────────┘

Security Considerations

  1. Heroscript Execution: The runner executes heroscripts via the hero CLI. Ensure job payloads are from trusted sources.
  2. Signature Verification: Always verify job signatures before execution.
  3. Environment Variables: Be cautious with sensitive data in environment variables.
  4. Hero CLI Access: Ensure the hero command is available in the system PATH.

Error Handling

The runner handles various error scenarios:

  • Hero CLI Not Found: Returns error if the hero command is not available
  • Timeout: Kills the process if it exceeds the job timeout
  • Non-zero Exit: Returns error if hero run -h exits with non-zero status
  • Heroscript Errors: Returns error output from the hero CLI

Logging

The runner logs to stdout/stderr with the following log levels:

  • INFO: Job start/completion, runner lifecycle
  • DEBUG: Command details, parsing information
  • ERROR: Execution failures, timeout errors

Integration with Supervisor

The Vlang runner integrates with the Hero Supervisor:

  1. Register the runner with the supervisor
  2. Supervisor queues jobs to the runner's Redis queue
  3. Runner polls the queue and executes commands
  4. Results are stored back in Redis

Development

Building

cargo build -p runner-hero

Running Tests

cargo test -p runner-hero

Running Locally

cargo run -p runner-hero -- test-runner

License

MIT OR Apache-2.0