# How Agent Reach Detects and Installs the GitHub CLI (gh)

> Agent Reach ensures GitHub CLI is present by checking `gh auth status` and automatically installing it when missing. Streamline your GitHub workflows effortlessly.

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

---

**Agent Reach detects the GitHub CLI by executing `gh auth status` probes in `GitHubChannel.check()` and automatically installs missing binaries via platform-specific commands in `_install_system_deps()`.**

Agent Reach is an open-source automation framework that integrates with GitHub through the official `gh` CLI tool. When users run the doctor or install commands, the system must verify that the GitHub CLI is present, functional, and properly authenticated before enabling GitHub channel operations.

## Runtime Detection in the GitHub Channel

The primary detection mechanism resides in the GitHub channel implementation, which probes the system to determine if the `gh` binary exists and executes correctly.

### The `GitHubChannel.check()` Method

In [`agent_reach/channels/github.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/github.py) (lines 19-42), the `check()` method utilizes a specialized probe to assess CLI availability:

```python
from agent_reach.probe import probe_command

probe = probe_command("gh", ["auth", "status"], timeout=10, package="gh")

```

This probe executes the `gh auth status` command with a 10-second timeout. The `probe_command` helper classifies the result into distinct states that determine the channel's operational status.

### Interpreting Probe Results

The detection logic handles four specific outcomes based on the probe's return status:

- **`missing`** – The `gh` binary is not found on the system `PATH`. The channel returns a warning status with installation instructions.
- **`broken`** – The binary exists but cannot execute (corrupted permissions or incomplete installation). The channel returns an error recommending reinstallation.
- **`ok` (authenticated)** – The CLI runs successfully and reports valid authentication. The channel sets `self.active_backend = "gh CLI"` and returns an "ok" status.
- **`ok` (unauthenticated)** – The CLI executes but returns a non-zero exit code indicating login is required. The channel marks the backend as active but returns a warning to run `gh auth login`.

## Automatic Installation via the CLI

When users execute `agent-reach install`, the system attempts to provision missing dependencies automatically, including the GitHub CLI.

### The `_install_system_deps()` Method

Located in [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py) (lines 31-71), the `_install_system_deps()` function first verifies existing installations using Python's `shutil` module:

```python
import shutil
import platform
import subprocess

if shutil.which("gh"):
    print("  ✅ gh CLI already installed")
else:
    print("  Installing gh CLI...")
    # Platform-specific installation logic follows

```

If `shutil.which("gh")` returns `None`, indicating the binary is absent, the installer proceeds to platform detection and automated installation.

### Platform-Specific Installation Logic

The installer supports automated provisioning on Linux and macOS, with fallback guidance for other platforms:

**Linux systems** – The code adds the official GitHub apt repository and executes `apt-get install gh` via subprocess:

```bash

# Executed via subprocess.run()

sudo apt-get update
sudo apt-get install -y gh

```

**macOS systems** – When Homebrew is detected (`shutil.which("brew")` returns a path), the installer runs:

```bash
brew install gh

```

**Other platforms** – If the operating system is neither Linux nor macOS, or if Homebrew is unavailable, the installer outputs a fallback message directing users to the manual download URL at `https://cli.github.com`.

After attempting installation, the code re-runs `shutil.which("gh")` to verify success and prints a status indicator (✅ for success, [!] for failure).

## Practical Code Examples

### Checking GitHub Channel Status

To verify whether Agent Reach detects the GitHub CLI correctly, use the doctor command:

```bash
$ agent-reach doctor --json | jq '.github'

```

When the CLI is missing, the output reflects the detection from `GitHubChannel.check()`:

```json
{
  "status": "warn",
  "message": "gh CLI 未安装。安装：https://cli.github.com",
  "active_backend": null
}

```

When installed but unauthenticated, the status shows:

```json
{
  "status": "warn",
  "active_backend": "gh CLI",
  "message": "gh CLI 已安装但未认证。运行 gh auth login …"
}

```

### Manual Probing for Debugging

Developers can manually invoke the probe logic used by the channel:

```python
from agent_reach.probe import probe_command

probe = probe_command("gh", ["auth", "status"], timeout=10, package="gh")
print(f"Status: {probe.status}, OK: {probe.ok}")

```

Expected outputs include:
- `missing False` – Binary not found in PATH
- `broken False` – Binary exists but cannot execute
- `ok True` – Command succeeded (authenticated)
- `ok False` – Binary runs but auth fails (unauthenticated)

### Running the Installer

To trigger automatic installation of the GitHub CLI:

```bash
$ agent-reach install

```

Output showing successful Linux installation:

```text
  Installing gh CLI...
  ✅ gh CLI installed
...
✅ Installation complete! 7/7 channels active.

```

## Key Implementation Files

The detection and installation logic spans three critical files in the repository:

| File | Purpose |
|------|---------|
| [`agent_reach/channels/github.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/github.py) | Contains `GitHubChannel.check()` (lines 19-42) that probes `gh auth status` and interprets missing, broken, or unauthenticated states. |
| [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py) | Houses `_install_system_deps()` (lines 31-71) with the `# ── gh CLI ──` block handling platform-specific installation via apt-get or Homebrew. |

| [`agent_reach/probe.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/probe.py) | Implements `probe_command()` used to execute external commands and classify results as `missing`, `broken`, `ok`, or `timeout`. |

## Summary

- **Detection** occurs in `GitHubChannel.check()` via `probe_command("gh", ["auth", "status"], ...)` which classifies the CLI as missing, broken, or functional.
- **Installation** is handled by `_install_system_deps()` in the CLI module, which uses `shutil.which("gh")` to check for the binary and executes platform-specific commands (apt-get for Linux, brew for macOS) when absent.
- **Verification** happens twice: once by the probe during channel checks and again by `shutil.which()` after installation attempts to confirm the binary is now available on PATH.

## Frequently Asked Questions

### How does Agent Reach verify that gh is installed and working?

Agent Reach uses the `probe_command` utility to execute `gh auth status` with a 10-second timeout. If the command returns successfully, the CLI is marked as present. If the binary is not found on PATH, the probe status returns `"missing"`; if the binary exists but cannot execute, it returns `"broken"`. This logic resides in [`agent_reach/channels/github.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/channels/github.py) within the `check()` method.

### What happens if the gh CLI is not installed when I run agent-reach install?

The `_install_system_deps()` function in [`agent_reach/cli.py`](https://github.com/Panniantong/Agent-Reach/blob/main/agent_reach/cli.py) detects the absence using `shutil.which("gh")` and attempts automatic installation. On Linux, it configures the official GitHub apt repository and runs `apt-get install gh`. On macOS with Homebrew present, it executes `brew install gh`. For unsupported platforms, it displays a manual installation URL.

### Why does Agent Reach report gh as "broken" instead of "missing"?

A "broken" status indicates that `shutil.which("gh")` found a binary at a specific path, but when the probe attempted to execute `gh auth status`, the process failed to run—likely due to permission issues, corrupted binaries, or incomplete installations. This distinction helps users understand whether they need a fresh installation (fixing the broken binary) versus a first-time installation (addressing a missing binary).

### Can Agent Reach use the GitHub channel if gh is installed but not authenticated?

Yes, but with limitations. The channel sets `active_backend = "gh CLI"` and remains functional for operations that do not require authentication. However, the `check()` method returns a warning status indicating that users should run `gh auth login` to enable full functionality. The system distinguishes between "installed but unauthenticated" and "installed and ready" by analyzing the exit code of the `auth status` command.