# Agent-Reach Installer: Understanding the `--safe` vs `--dry-run` Distinction

> Understand the difference between Agent-Reach installer's --safe and --dry-run flags. Learn how --safe checks dependencies and --dry-run simulates installation without making changes.

- Repository: [Pnant/Agent-Reach](https://github.com/Panniantong/Agent-Reach)
- Tags: how-to-guide
- Published: 2026-07-14

---

**The `--safe` flag audits missing dependencies without installing them, while `--dry-run` simulates the full installation workflow including optional channels and cookie imports, prefixing every action with `[dry-run]`.**

The Agent-Reach installer provides two mutually exclusive modes for validating setup procedures without modifying your host system. Understanding the distinction between `--safe` mode and `--dry-run` is essential for system administrators who need to audit dependencies or preview complex installations. Both flags are implemented in [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py) and control how the installer handles system dependencies, optional channels, and browser cookie extraction.

## How `--safe` Mode Works

**`--safe` mode** performs a read-only audit of your environment. When you invoke `agent-reach install --safe`, the installer skips all automatic system modifications and only reports what packages or configurations are missing.

In [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py), the implementation routes to safe-specific helper functions. At lines 50 and 58, the code calls `_install_system_deps_safe()` and `_install_mcporter_safe()` respectively【`https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py#L45-L61`】. These checking-only variants verify whether `ffmpeg`, `libmagic`, and other system libraries are present without invoking `apt`, `brew`, or pip commands.

The installer also prints a "SAFE MODE" banner at lines 92-95 to make the non-destructive state obvious to the user【`https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py#L92-L95`】. Additionally, when `--safe` is active, the optional channel installation and cookie import steps are completely disabled, ensuring zero network or filesystem activity.

## How `--dry-run` Mode Works

**`--dry-run` mode** performs a complete simulation of the installation process. Unlike `--safe`, which only checks prerequisites, `--dry-run` walks through every actionable step and prints the exact commands it would have executed, prefixed with `[dry-run]`.

The implementation branches at line 47 to call `_install_system_deps_dryrun()`【`https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py#L45-L53`】. This helper emits simulation messages for system package installations while still running the dependency checks.

Crucially, `--dry-run` includes optional workflow steps that `--safe` suppresses. At lines 80-82, if optional channels are requested, the installer prints a summary line indicating which channels would be installed【`https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py#L80-L82`】. Similarly, at lines 88-90, cookie extraction from Chrome or Firefox is simulated with a placeholder message【`https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py#L88-L90`】. This gives you a complete view of the installer’s behavior, including optional features, without affecting the environment at all.

## Key Implementation Differences

### Argument Parsing and Variable Assignment

Both flags are defined in the `install` sub-parser at lines 71 and 73 of [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py)【`https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py#L71-L74`】. The parsed values are immediately read into local variables at lines 177-179: `safe_mode = args.safe` and `dry_run = args.dry_run`【`https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py#L177-L179`】.

### System Dependency Branching Logic

The three-way conditional at lines 45-53 determines which helper executes:

- `dry_run` → `_install_system_deps_dryrun()` (line 47)
- `safe_mode` → `_install_system_deps_safe()` (line 50)
- Default → `_install_system_deps()` (line 52)

The same pattern applies to mcporter installation at lines 55-61, with dedicated safe and dry-run variants【`https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py#L55-L61`】.

### Optional Channel Execution Rules

Optional channels are installed only when **both** `dry_run` and `safe_mode` are false, as enforced by the condition at lines 69-71【`https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py#L69-L71`】. This ensures that `--safe` mode remains a lightweight audit tool, while `--dry-run` provides the full execution preview.

### Cookie Exclusion Logic

Browser cookie extraction follows similar exclusion rules. The actual import runs only in `local` environments when cookies are needed and neither flag is set (lines 84-86). The `dry_run` variant prints a simulation message instead, while `safe_mode` skips the step entirely【`https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py#L84-L90`】.

## Practical Usage Examples

Use `--safe` when you need a quick health check of system dependencies:

```bash

# Safe mode - only reports missing system packages

agent-reach install --safe

```

Use `--dry-run` when you need to verify the complete installation plan, including optional components:

```bash

# Dry-run mode - shows full plan including channels and cookies

agent-reach install --dry-run --channels=twitter,reddit,bilibili

```

Running these commands produces output similar to:

```

SAFE MODE — skipping automatic system changes

System dependency check:
  [safe] Would install ffmpeg, libmagic, etc.

```

Or for dry-run:

```

[dry-run] Would install system dependencies: ffmpeg, libmagic
[dry-run] Would install optional channels: twitter, reddit, bilibili
[dry-run] Would try to import cookies from Chrome/Firefox

```

## Summary

- **`--safe` mode** audits missing dependencies using `_install_system_deps_safe()` and disables optional features to provide a lightweight system check.
- **`--dry-run` mode** simulates every installation step, including optional channels and cookie imports, with `[dry-run]` prefixes via `_install_system_deps_dryrun()`.
- Both flags are defined in [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py) (lines 71, 73) and stored in local variables at lines 177-179.
- Optional channels and cookie extraction only execute when neither flag is active, as controlled by conditionals at lines 69-71 and 84-86.
- Use `--safe` for dependency audits and `--dry-run` for complete workflow validation before production deployment.

## Frequently Asked Questions

### Can I use `--safe` and `--dry-run` together?

No, these flags are mutually exclusive by design. The installer logic in [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py) treats them as distinct branches in the conditional flow at lines 45-53. While the argument parser technically allows both to be passed, the internal logic prioritizes `dry_run` checks first, then `safe_mode`, ensuring only one simulation path executes.

### When should I use `--safe` mode versus `--dry-run`?

Use **`--safe`** when you need a rapid audit of system prerequisites without verbose output about optional features. It runs `_install_system_deps_safe()` and skips channel installation entirely. Use **`--dry-run`** when you need to validate the complete installation recipe, including which pip packages would install for optional channels like Twitter or Reddit, and whether cookie extraction would succeed.

### Does `--dry-run` actually check if system dependencies are installed?

Yes, `--dry-run` still executes the checking logic to determine what would need installation. According to the source at line 47, it calls `_install_system_deps_dryrun()`, which performs the same prerequisite verification as the safe mode but additionally emits the `[dry-run]` prefixed messages showing what commands would execute if the installation were real.

### Where are these behaviors tested in the codebase?

The test suite in [`tests/test_cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/tests/test_cli.py) validates both the `--safe` and `--dry-run` behaviors, ensuring they produce the expected output strings and exit codes. Additional integration with [`agent_reach/doctor.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/doctor.py) provides the `check_all` utilities invoked after installation steps, while [`agent_reach/config.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/config.py) handles configuration objects that would be written during a real installation (affected by the dry-run simulation).