A cross-platform automation tool that runs tasks when conditions are met. Write once, run on Linux, macOS, and Windows.
Define a job, set conditions, list tasks. AutoPilot does the rest.
AutoPilot checks: Are you on office WiFi? Are your headphones connected? If both yes, run the tasks. Simple.
Download latest released version from GitHub Releases
# not available right now, but hopefully available someday
brew install autopilot-rs
# or build from source
cargo build --release
./target/release/autopilot-rs --helpcargo build --release
./target/release/autopilot-rs --helpcargo build --release
.\target\release\autopilot-rs.exe --helpautopilot-rs createOr manually create a JSON file in ~/.autopilot-rs/jobs/my-job.jsonc
autopilot-rs serveAutoPilot runs in the background, checking conditions and running tasks.
autopilot-rs listSee all your jobs and their status.
autopilot-rs removeautopilot-rs stopAutoPilot supports 14 condition types for flexible automation. For complete documentation on each condition type, see docs/CONDITIONS.md.
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,
},
}For more other condition types like Screen, Logical, and others, please refer to the complete documentation in docs/CONDITIONS.md.
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.
{
"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)
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).
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 helpAutoPilot reads from ~/.auto_pilot/:
~/.auto_pilot/
├── jobs/
│ ├── morning.jsonc
│ ├── evening.jsonc
│ └── cleanup.jsonc
├── status.jsonc
│
└── logs/
└── autopilot.log
{
"id": "sync-home-wifi",
"name": "Sync files when on home network",
"conditions": [{ "type": "wifi", "condition": { "ssid": "HomeNetwork" } }],
"tasks": [{ "command": "rsync -av ~/Documents /mnt/nas" }],
}{
"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" },
],
}{
"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" },
],
}{
"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" }],
}{
"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" },
],
}Check if daemon is running:
autopilot-rs listIf it hangs, daemon isn't running:
autopilot-rs serveCheck 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>.logEnable verbose mode:
autopilot-rs serve --verbose- Test the command manually in your shell
- Check exact paths (use absolute paths, not
~) - Check file permissions
- Check environment variables are set
- See docs/TROUBLESHOOTING.md for detailed guides
- 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
| 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.
- CONDITIONS.md - Detailed condition reference (12 types)
- PLUGIN-SYSTEM.md - Extend AutoPilot with custom plugins (coming soon)
- https://deepwiki.com/streamtechteam/auto_pilot_rs
- https://github.com/copilot and start chat with
#@streamtechteam/auto_pilot_rs
- Check existing issues
- Open an issue or PR on GitHub
- Follow the code style (cargo fmt, cargo clippy)
MIT
- 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)
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.

{ "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!'" }, ], }