remote-exec 0.1.0

Remote code execution + folder sync over SSH with auto-reconnect resilience
# rexec — Remote Code Execution + Folder Sync

A simple CLI tool to sync local folders and execute commands on remote hosts over SSH, designed to survive SSH disconnections.

## Features

- **Folder sync**: rsync local directory to remote before execution
- **Remote execution**: commands run via `nohup`, surviving SSH disconnects
- **Log following**: streams remote output back to local terminal with offset tracking
- **Auto-reconnect**: exponential backoff reconnection on SSH disconnect
- **Dependency check**: `init` command checks and auto-installs remote deps
- **SSH config**: resolves host aliases from `~/.ssh/config`
- **Authentication**: SSH agent → identity file → default keys

## Install

```bash
cargo build --release
cp target/release/rexec ~/.local/bin/
```

## Usage

```bash
# Check and install remote dependencies (run once per host)
rexec <host> init

# Sync a folder and run a command
rexec <host> run --sync local_dir:remote_dir -- "bash deploy.sh"

# Run a command without syncing
rexec <host> run -- "python train.py --epochs 100"

# Use with ssh config alias
rexec my-server run --sync ./project:/home/user/project -- "cd /home/user/project && python main.py"

# Direct user@host:port
rexec root@192.168.1.100:22 run -- "df -h"
```

## How it works

1. If `--sync` is given, runs `rsync -az --delete -e ssh` to sync the local folder to remote
2. Connects via russh (pure Rust SSH), authenticates via agent/keys
3. Wraps the command in `nohup sh -c '...' > /tmp/rexec_<pid>_<rand>.log 2>&1 &`
4. Polls the remote log file, streaming new content to local stdout
5. On SSH disconnect: exponential backoff retry (1s→30s, max 10), resumes from last offset
6. On process completion: prints exit status

## SSH Disconnection Behavior

- Remote process **continues running** via `nohup` (not killed when SSH drops)
- Local CLI **auto-reconnects** with exponential backoff
- Log output **resumes from last byte offset** — no data lost
- If reconnection fails after 10 retries, prints remote log file path and exits
- The log file persists at `/tmp/rexec_<pid>_<rand>.log` on the remote

## `init` Command

Checks if `rsync`, `sh`, `nohup` exist on the remote host. If missing, auto-detects the package manager (`apt-get`/`yum`/`dnf`/`apk`/`pacman`) and installs them.

```bash
rexec my-server init
```

## Build

```bash
cargo build --release
# Binary at target/release/rexec
```

## Dependencies

- `russh` — pure Rust SSH client
- `ssh2-config` — parse ~/.ssh/config
- `rsync` (system) — required for folder sync (local + remote)