torzy 0.1.0

Minimal Tor-routed worker launcher library and CLI
Documentation
# torzy

`torzy` is a small Rust library and CLI for running isolated worker commands
behind separate Tor SOCKS routes.

It handles the Tor lifecycle, worker isolation, command execution, timeouts, and
sanitized status reporting. It does not include project-specific workflows or
application launch logic.

## Privacy Defaults

- The default command is local and does not call an external service.
- CLI output does not print Tor route addresses, process ids, runtime paths, or
  public network addresses from worker output.
- JSON summaries contain counts and worker statuses only.
- Route strings are passed to workers through `TOR_ROUTE` and proxy environment
  variables, but they are not printed by `torzy` itself.

Worker commands can still print their own data. `torzy` redacts common route and
public-address tokens from captured output, but callers should avoid logging
sensitive data in the command they provide.

## Install

```bash
cargo install torzy
```

Managed Tor mode requires a `tor` binary on `PATH`, or pass `--tor-binary`.

## CLI

Dry-run the default five workers without starting Tor:

```bash
torzy --dry-run
```

Start five managed Tor routes and run the safe default command:

```bash
torzy
```

Set the worker count and command:

```bash
torzy -n 10 -c 'printf "worker=%s ready\n" "$TOR_WORKER_ID"'
```

Use existing SOCKS routes instead of managed Tor:

```bash
torzy --no-manage-tor \
  --tor-routes socks5h://localhost:9050,socks5h://localhost:9051 \
  -n 2
```

Supported command placeholders:

- `{TOR_ROUTE}`
- `{TOR_WORKER_ID}` or `{WORKER_ID}`
- `{TORZY_ROOT}`
- `{TORZY_WORKSPACE}`

Workers also receive `TOR_ROUTE`, `TOR_WORKER_ID`, `TORZY_ROOT`,
`TORZY_WORKSPACE`, isolated `HOME`, `TMPDIR`, `CARGO_HOME`, and
`CARGO_TARGET_DIR`. Proxy environment variables are enabled by default and can
be disabled with `--no-proxy-env`.

## Library

```rust
use torzy::{run, LaunchConfig};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let summary = run(
        LaunchConfig {
            envs: 5,
            dry_run: true,
            ..LaunchConfig::default()
        },
        None,
    )
    .await?;

    println!("{} workers succeeded", summary.succeeded);
    Ok(())
}
```

Use `tokio::sync::mpsc::unbounded_channel` with `run(config, Some(tx))` when you
want live events for a UI or supervisor.