# How the Agent-Reach Install Command Detects System Dependencies

> Discover how the agent-reach install command automatically detects and installs system dependencies like GitHub CLI, Node.js, and npm. Use dry run and safe flags to manage changes.

- Repository: [Pnant/Agent-Reach](https://github.com/Panniantong/Agent-Reach)
- Tags: internals
- Published: 2026-06-06

---

**The `agent-reach install` command detects missing system tools—including GitHub CLI, Node.js, and npm—and installs them automatically using platform-specific logic, while `--dry-run` and `--safe` flags let you preview or restrict system changes.**

The `agent-reach install` command in the `Panniantong/Agent-Reach` repository is a deterministic one-shot installer designed to prepare a host for Agent Reach channels. Understanding how its **system dependency detection** works helps operators decide when to use automatic installation versus guarded modes on local workstations or remote servers. The core logic lives in [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py), where environment sensing and dependency verification run before any system modifications occur.

## High-Level Execution Flow

The installation process defined in `_cmd_install` inside [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py) follows a strict sequence before it modifies the host:

1. **Parse user flags** such as `--dry-run`, `--safe`, `--env`, and `--channels`.
2. **Detect the execution environment** by calling `_detect_environment()`. This routine counts indicators like SSH variables, Docker markers, headless displays, cloud VM identifiers, and output from `systemd-detect-virt`. If two or more server-like indicators appear, it returns `"server"`; otherwise it returns `"local"` (see lines 975–1014).
3. **Select an installer routine** based on flags. Normal runs invoke `_install_system_deps()`, while `--dry-run` triggers `_install_system_deps_dryrun` and `--safe` triggers `_install_system_deps_safe`.
4. **Detect and install core system dependencies** inside `_install_system_deps()` (lines 484–560).
5. **Run optional channel installers** only when the user passes `--channels` and the run is not in dry-run or safe mode (see lines 80–89 of `_cmd_install`).
6. **Extract browser cookies** automatically for channels that require them—such as Twitter, Xueqiu, or Bilibili—via `agent_reach.cookie_extract.configure_from_browser`, but only on local machines and outside safe/dry-run modes (lines 52–74 of `_cmd_install`).
7. **Verify health** by calling `doctor.check_all` from [`agent_reach/doctor.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/doctor.py) and printing a concise report.

## Core System Dependency Detection in `_install_system_deps`

Inside [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py), the `_install_system_deps` function (lines 484–560) performs three independent checks to confirm the host can support Agent Reach.

### GitHub CLI (`gh`) Detection

The installer uses `shutil.which("gh")` to verify that the GitHub CLI is on the system `PATH`. If the binary is absent, the script attempts a platform-specific installation: it prefers **APT** on Linux distributions and **Homebrew** on macOS. When automated installation is not possible, it prints user-friendly fallback URLs so the operator can complete the step manually (see lines 94–124 of `_install_system_deps`).

### Node.js and npm Verification

Agent Reach requires both the `node` and `npm` binaries. The function calls `shutil.which("node")` and `shutil.which("npm")` to confirm their presence. If either binary is missing, the installer downloads the **NodeSource** setup script, executes it, and runs `apt-get install nodejs`. Any errors are caught and surfaced as a concise fallback message instead of a stack trace (see lines 141–172 of `_install_system_deps`).

### `undici` npm Package Check

Because some channels rely on Node.js fetch with proxy support, the installer confirms that the **`undici`** package is available globally. It runs `npm root -g` to locate the global package directory and checks for [`undici/index.js`](https://github.com/Panniantong/Agent-Reach/blob/main/undici/index.js). If the file is missing, it executes `npm install -g undici` to add the package (see lines 173–180 of `_install_system_deps`).

## Environment Detection and Installer Modes

Before any dependency check runs, the installer decides how aggressively it should act based on runtime signals and user flags.

### Local vs. Server Detection

The `_detect_environment()` function in [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py) (lines 975–1014) inspects the runtime for server-like characteristics. It tallies evidence such as active SSH sessions, Docker containers, headless displays, cloud VM identity files, and virtualization data from `systemd-detect-virt`. When the count reaches two or more indicators, the function classifies the host as `"server"`, which influences downstream decisions like cookie extraction eligibility.

### Dry-Run and Safe Mode Implementations

- **`--dry-run`** activates `_install_system_deps_dryrun`, which prints every intended action without writing to the system. This mode is useful for CI pipelines and pre-check audits.
- **`--safe`** activates `_install_system_deps_safe`, which reports the current presence or absence of dependencies but refuses to modify the system. It is designed for fragile VMs or shared hosts where automatic package management is restricted.

Both modes skip the optional channel installers and cookie extraction steps regardless of the `--channels` flag.

## Optional Channels and Cookie Extraction

After core dependencies are satisfied, the installer evaluates the `--channels` argument. Valid channels are mapped in `CHANNEL_INSTALLERS` (around lines 80–89 of `_cmd_install`). Each selected channel’s installer runs only in normal mode.

If a requested channel requires authentication cookies—such as Twitter, Xueqiu, or Bilibili—the installer invokes `agent_reach.cookie_extract.configure_from_browser` to import cookies from Chrome or Firefox. This step is deliberately disabled on server-classified hosts and blocked in dry-run and safe modes.

## Final Verification with the Doctor Check

Regardless of which mode runs, the command ends by calling `doctor.check_all` from [`agent_reach/doctor.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/doctor.py). This routine audits every enabled channel and emits a concise report. If the installer performed work, the doctor output confirms whether the environment is now healthy; if the run was a dry-run or safe check, the report describes what remains missing.

## Practical Examples

Use these commands to control how system dependency detection behaves on your host.

```bash

# Normal installation—detects missing deps and installs them

agent-reach install

```

```bash

# Preview what would change without modifying the system

agent-reach install --dry-run

```

```bash

# Audit dependencies without installing anything

agent-reach install --safe

```

```bash

# Install optional channels in addition to core dependencies

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

```

```bash

# Force server-type detection on a remote VPS

agent-reach install --env=server

```

## Summary

- The `agent-reach install` command detects core system dependencies—**GitHub CLI**, **Node.js**, **npm**, and the **`undici`** package—using `shutil.which` and global npm path checks inside [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py).
- **Environment detection** in `_detect_environment()` classifies the host as `"local"` or `"server"` based on SSH, Docker, display, and virtualization indicators.
- **`--dry-run`** previews changes, and **`--safe`** audits the system without making modifications.
- Optional **channel installers** and **cookie extraction** run only after core dependencies are resolved, and only when explicitly requested.
- Every run concludes with a **health report** from `doctor.check_all` to confirm channel readiness.

## Frequently Asked Questions

### What system dependencies does `agent-reach install` check for?

The installer checks for the **GitHub CLI** (`gh`) via `shutil.which("gh")`, **Node.js** and **npm** via `shutil.which("node")` and `shutil.which("npm")`, and the **`undici`** npm package by reading the global npm root for [`undici/index.js`](https://github.com/Panniantong/Agent-Reach/blob/main/undici/index.js) inside [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py).

### How does the installer decide whether the host is a local workstation or a server?

The `_detect_environment()` function in [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py) inspects SSH variables, Docker markers, headless displays, cloud VM identifiers, and `systemd-detect-virt` output. If two or more server-like indicators are present, it returns `"server"`; otherwise it returns `"local"`.

### Will `agent-reach install --safe` modify my system packages?

No. Safe mode uses `_install_system_deps_safe` to report the presence or absence of dependencies without installing anything. It also skips optional channel installers and browser cookie extraction.

### Why does the installer require the `undici` npm package globally?

Agent Reach leverages Node.js fetch with proxy support for certain channels. The installer verifies that [`undici/index.js`](https://github.com/Panniantong/Agent-Reach/blob/main/undici/index.js) exists in the global npm directory, and if not, it runs `npm install -g undici` to ensure the runtime requirement is met.