Skip to content

streamtechteam/autopilot-rs

Repository files navigation

Alt Text

Ask DeepWiki

AutoPilot-rs

A cross-platform automation tool that runs tasks when conditions are met. Write once, run on Linux, macOS, and Windows.

What It Does

Define a job, set conditions, list tasks. AutoPilot does the rest.

{
  "id": "morning-setup",
  "name": "Setup my workday",
  "when": {
    "time": "08:00:00",
    "date": "2026/02/02",
  },
  "conditions": [
    { "type": "wifi", "condition": { "ssid": "OfficeNetwork" } },
    { "type": "bluetooth", "condition": { "device": "My Headphones" } },
  ],
  "tasks": [
    { "command": "open /Applications/Slack.app" },
    { "command": "open /Applications/VSCode.app" },
    { "command": "notify-send 'Good morning!'" },
  ],
}

AutoPilot checks: Are you on office WiFi? Are your headphones connected? If both yes, run the tasks. Simple.

Installation

Release

Download latest released version from GitHub Releases

macOS

# not available right now, but hopefully available someday
brew install autopilot-rs
# or build from source
cargo build --release
./target/release/autopilot-rs --help

Linux

cargo build --release
./target/release/autopilot-rs --help

Windows

cargo build --release
.\target\release\autopilot-rs.exe --help

Quick Start

1. Create a Job

autopilot-rs create

Or manually create a JSON file in ~/.autopilot-rs/jobs/my-job.jsonc

2. Start the Daemon

autopilot-rs serve

AutoPilot runs in the background, checking conditions and running tasks.

3. List Jobs

autopilot-rs list

See all your jobs and their status.

4. Remove job

autopilot-rs remove

5. Stop AutoPilot

autopilot-rs stop

Condition Types

AutoPilot supports 14 condition types for flexible automation. For complete documentation on each condition type, see docs/CONDITIONS.md.

Basic Condition Examples

WiFi - Run when connected to a specific network:

{
  "type": "wifi",
  "condition": { "ssid": "HomeNetwork" },
}

Bluetooth - Run when a device is connected:

{
  "type": "bluetooth",
  "condition": {
    "device": "My Headphones",
    "match_by_mac": false,
  },
}

Command - Run a shell command and check the result:

{
  "type": "command",
  "condition": {
    "command": "test -f /tmp/trigger-file",
    "check_exit_code": true,
  },
}

Variable - Check environment variables:

{
  "type": "variable",
  "condition": {
    "variable": "USER",
    "target": "alice",
  },
}

Power - Check battery status or charging:

{
  "type": "power",
  "condition": {
    "check_charging": true,
  },
}

Other Conditions

For more other condition types like Screen, Logical, and others, please refer to the complete documentation in docs/CONDITIONS.md.

Multiple Conditions

All conditions must be true (AND logic):

{
  "conditions": [
    { "type": "wifi", "condition": { "ssid": "Office" } },
    { "type": "bluetooth", "condition": { "device": "My Headphones" } },
    { "type": "power", "condition": { "check_charging": true } },
  ],
}

If any condition fails, the task doesn't run.

Job Structure

{
  "id": "unique-job-id",
  "name": "Human readable name",
  "description": "What this job does",
  "when": {
    "time": "08:00:00",
    "date": "2026/02/02",
  },
  // check conditions every 1000 milliseconds (1 second)
  "check_interval": "1000",
  "conditions": [
    // Zero or more conditions
  ],
  "tasks": [
    // One or more tasks
    { "command": "echo 'Hello'" },
    { "command": "touch /tmp/file" },
  ],
}
  • id: Unique identifier (required)
  • name: Display name for humans (optional)
  • description: What this job does (optional)
  • when: When to run the job (optional, defaults to run at autopilot startup)
  • check_interval: If a condition fails, autopilot will check it again every x milliseconds
  • conditions: List of conditions to check (optional, defaults to always run)
  • tasks: List of commands to execute (required)

Tasks

Each task is a shell command:

{
  "command": "ls -la /home",
}

Or multi-step with pipes:

{
  "command": "cat /var/log/system.log | grep ERROR | wc -l",
}

Tasks run sequentially. If one fails, remaining tasks still run (for now).

CLI Commands

autopilot-rs serve              # Start daemon
autopilot-rs stop               # Stop daemon
autopilot-rs list               # List all jobs
autopilot-rs create             # Create new job
autopilot-rs remove             # Remove a job
autopilot-rs --verbose          # Verbose logging
autopilot-rs --help             # Show help

Configuration

AutoPilot reads from ~/.auto_pilot/:

~/.auto_pilot/
├── jobs/
│   ├── morning.jsonc
│   ├── evening.jsonc
│   └── cleanup.jsonc
├── status.jsonc
│
└── logs/
    └── autopilot.log

Examples

Sync files only on home WiFi

{
  "id": "sync-home-wifi",
  "name": "Sync files when on home network",
  "conditions": [{ "type": "wifi", "condition": { "ssid": "HomeNetwork" } }],
  "tasks": [{ "command": "rsync -av ~/Documents /mnt/nas" }],
}

Morning routine

{
  "id": "morning-routine",
  "name": "Morning setup",
  "when": {
    "time": "08:00:00",
    "date": "2026/02/02",
  },
  "conditions": [
    { "type": "bluetooth", "condition": { "device": "Headphones" } },
    { "type": "wifi", "condition": { "ssid": "HomeNetwork" } },
  ],
  "tasks": [
    { "command": "brew update" },
    { "command": "notify-send 'Good morning!'" },
    { "command": "open /Applications/Mail.app" },
  ],
}

Run when device connects

{
  "id": "headphones-connected",
  "name": "Play sound when headphones connect",
  "conditions": [
    { "type": "bluetooth", "condition": { "device": "Sony Headphones" } },
  ],
  "tasks": [
    { "command": "pactl set-default-sink 'Sony Headphones'" },
    { "command": "speaker-test -t sine -f 1000 -l 1" },
  ],
}

Run only when system is idle

{
  "id": "idle-backup",
  "name": "Backup when CPU is idle",
  "conditions": [
    {
      "type": "resource",
      "condition": {
        "resource_type": "cpu",
        "threshold": 20,
        "operator": "less",
      },
    },
    {
      "type": "power",
      "condition": { "check_charging": true },
    },
  ],
  "tasks": [{ "command": "backup.sh" }],
}

Conditional based on file

{
  "id": "process-if-ready",
  "name": "Process when trigger file exists",
  "conditions": [
    {
      "type": "file",
      "condition": {
        "path": "/tmp/ready-to-process",
        "check_type": "exists",
      },
    },
  ],
  "tasks": [
    { "command": "process_data.sh" },
    { "command": "rm /tmp/ready-to-process" },
  ],
}

Troubleshooting

Jobs not running

Check if daemon is running:

autopilot-rs list

If it hangs, daemon isn't running:

autopilot-rs serve

Check condition logic:

Run conditions manually to debug:

# Test WiFi
nmcli dev show | grep CONNECTION

# Test custom command
test -f /tmp/file && echo "Exists" || echo "Missing"

Check logs:

tail -f ~/.config/auto_pilot/logs/<logdate>.log

Enable verbose mode:

autopilot-rs serve --verbose

Condition not working

  1. Test the command manually in your shell
  2. Check exact paths (use absolute paths, not ~)
  3. Check file permissions
  4. Check environment variables are set
  5. See docs/TROUBLESHOOTING.md for detailed guides

Task execution issues

  • Commands must be shell-compatible (sh, zsh, PowerShell depending on OS)
  • Use absolute paths for commands
  • Redirect errors to see what went wrong: command 2>&1
  • Test commands manually first

Platform Support

Feature Linux macOS Windows
WiFi detection
Bluetooth detection
Command execution
Variables
Power/Battery
Resource (CPU/RAM)
Internet check
Process monitoring
Disk space
File monitoring
External devices
Screen/Monitor
Logical

All 13 condition types work on all platforms.

Documentation

AI powered docs

Contributing

  1. Check existing issues
  2. Open an issue or PR on GitHub
  3. Follow the code style (cargo fmt, cargo clippy)

License

MIT

Roadmap

  • Plugin system for custom conditions
  • REST API for job management
  • Web dashboard
  • Performance optimizations
  • Metrics and monitoring
  • 13 condition types (WiFi, Bluetooth, Command, Variable, Power, Resource, Internet, Process, DiskSpace, File, ExternalDevice, Screen, Logical)

FAQ

Q: Can I run multiple jobs?
A: Yes. Define as many jobs as you need. All conditions are checked independently.

Q: What happens if a task fails?
A: Currently, remaining tasks still run. Error is logged.

Q: Can I use environment variables in commands?
A: Yes. Shell expands them: { "command": "$HOME/backup.sh" }

Q: Does it work on minimal systems?
A: Mostly. Dependencies are minimal. Check docs for platform-specific requirements.

Q: Can I use this with cron?
A: Yes, but AutoPilot is designed to replace constant cron tasks with condition-based execution.

Q: How many condition types are supported?
A: 14 condition types: WiFi, Bluetooth, Command, Variable, Power, Resource, Internet, Process, DiskSpace, File, ExternalDevice, Screen, And, and Or.


Built with Rust.

About

an automation tool written in rust with the goal of being easy to use and cross plaform

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors