# How SwarmForge Terminal Auto-Detection Works and How to Override It Manually

> Discover how SwarmForge terminal auto-detection works using its priority flow and learn to manually override it with the SWARMFORGE_TERMINAL environment variable.

- Repository: [Robert C. Martin/swarm-forge](https://github.com/unclebob/swarm-forge)
- Tags: internals
- Published: 2026-09-01

---

**SwarmForge automatically detects your terminal emulator through a four-step priority flow in [`swarm-terminal-adapter.sh`](https://github.com/unclebob/swarm-forge/blob/main/swarm-terminal-adapter.sh), with manual override available via the `SWARMFORGE_TERMINAL` environment variable.**

SwarmForge is an open-source swarm robotics deployment framework that needs to communicate with your terminal to manage window control, tab creation, and session cleanup. This article explains the exact detection algorithm implemented in the unclebob/swarm-forge repository and documents every manual override option for power users.

## The Terminal Detection Flow

The **`detect_terminal_backend`** function in [[`swarmforge/scripts/swarm-terminal-adapter.sh`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/scripts/swarm-terminal-adapter.sh)](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/scripts/swarm-terminal-adapter.sh) implements a deterministic priority system. SwarmForge evaluates four conditions in strict order and stops at the first match.

### Step 1: Explicit Environment Variable

If `SWARMFORGE_TERMINAL` is set, SwarmForge immediately passes its value to **`normalize_terminal_backend`** and uses the result. This bypasses all platform detection logic.

### Step 2: macOS Detection

When `osascript` (the AppleScript interpreter) is available, SwarmForge inspects `TERM_PROGRAM`:

- **`iTerm.app`** → selects the **iTerm2** adapter
- **Any other value** → falls back to **Terminal.app**

### Step 3: Windows Detection

If `wt.exe` (Windows Terminal executable) exists in the system path, SwarmForge selects the **Windows Terminal** adapter. This triggers even inside WSL environments where Windows Terminal is the host.

### Step 4: Fallback to None

When no conditions match, `detect_terminal_backend` returns **`none`**. This disables all terminal-control features but allows SwarmForge core operations to continue.

## How the Backend Loader Works

After detection completes, the normalized backend string flows to **`load_terminal_backend`**. This function sources the corresponding adapter script from [`swarmforge/scripts/terminal-adapters/`](https://github.com/unclebob/swarm-forge/tree/main/swarmforge/scripts/terminal-adapters), which contains:

- [[`iterm2.sh`](https://github.com/unclebob/swarm-forge/blob/main/iterm2.sh)](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/scripts/terminal-adapters/iterm2.sh) — iTerm2-specific AppleScript commands
- [[`terminal-app.sh`](https://github.com/unclebob/swarm-forge/blob/main/terminal-app.sh)](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/scripts/terminal-adapters/terminal-app.sh) — macOS Terminal.app integration
- [[`windows-terminal.sh`](https://github.com/unclebob/swarm-forge/blob/main/windows-terminal.sh)](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/scripts/terminal-adapters/windows-terminal.sh) — Windows Terminal control sequences

Each adapter implements a common interface: window creation, tab management, and cleanup hooks specific to that terminal's API.

## Manual Override Options

SwarmForge provides two environment variables for explicit backend control.

### SWARMFORGE_TERMINAL — Primary Override

Set this variable before invoking any SwarmForge command to force a specific backend:

```bash
export SWARMFORGE_TERMINAL=windows-terminal
swarmforge

```

Valid values match the canonical identifiers recognized by `normalize_terminal_backend`:
- `iterm2`
- `terminal-app`
- `windows-terminal`
- `none`
- Any custom adapter name present in the `terminal-adapters/` directory

### SWARMFORGE_TERMINAL_BACKEND — Secondary Override

Used by helper scripts such as [[`swarm-cleanup.sh`](https://github.com/unclebob/swarm-forge/blob/main/swarm-cleanup.sh)](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/scripts/swarm-cleanup.sh). This overrides the default `terminal-app` backend specifically for cleanup operations:

```bash
export SWARMFORGE_TERMINAL_BACKEND=iterm2
swarmforge-cleanup

```

This separation allows your main SwarmForge session to use one terminal while cleanup scripts target another.

## Practical Code Examples

### Auto-Detection (Default Behavior)

```bash
swarmforge

```

The `detect_terminal_backend` function runs internally with no user configuration required.

### Force iTerm2 on macOS

```bash
export SWARMFORGE_TERMINAL=iterm2
swarmforge

```

Useful when `TERM_PROGRAM` detection fails or you run iTerm2 in compatibility mode.

### Force Windows Terminal on WSL

```bash
export SWARMFORGE_TERMINAL=windows-terminal
swarmforge

```

Ensures Windows Terminal control even when WSL's `TERM_PROGRAM` reports a Linux value.

### Disable Terminal Control Entirely

```bash
export SWARMFORGE_TERMINAL=none
swarmforge

```

Runs SwarmForge without window management—useful for CI/CD pipelines or headless servers.

### Override Cleanup Script Backend Only

```bash
export SWARMFORGE_TERMINAL_BACKEND=terminal-app
swarmforge-cleanup

```

Directs the cleanup utility to Apple's Terminal.app regardless of the main session's terminal choice.

## Summary

- **Auto-detection priority**: `SWARMFORGE_TERMINAL` → macOS `TERM_PROGRAM` check → Windows `wt.exe` check → `none` fallback
- **Primary override**: `export SWARMFORGE_TERMINAL=<backend>` forces any valid adapter
- **Secondary override**: `export SWARMFORGE_TERMINAL_BACKEND=<backend>` controls helper scripts like [`swarm-cleanup.sh`](https://github.com/unclebob/swarm-forge/blob/main/swarm-cleanup.sh)
- **Backend loader**: `load_terminal_backend` sources scripts from `swarmforge/scripts/terminal-adapters/`
- **Canonical identifiers**: `iterm2`, `terminal-app`, `windows-terminal`, `none`, plus custom adapters

## Frequently Asked Questions

### How do I know which terminal SwarmForge detected?

SwarmForge does not print detection results by default. Set `SWARMFORGE_TERMINAL` explicitly to verify behavior, or inspect the sourced adapter by adding `echo "Using backend: $SWARMFORGE_TERMINAL"` after the `detect_terminal_backend` call in [`swarm-terminal-adapter.sh`](https://github.com/unclebob/swarm-forge/blob/main/swarm-terminal-adapter.sh).

### Can I use a custom terminal adapter?

Yes. Place a shell script implementing the adapter interface in `swarmforge/scripts/terminal-adapters/`, then set `SWARMFORGE_TERMINAL` to your custom name (matching the filename without `.sh` extension). The `normalize_terminal_backend` function accepts any string present in that directory.

### Why does SwarmForge detect `none` on my Linux workstation?

The detection algorithm prioritizes macOS and Windows terminals. Native Linux terminals (GNOME Terminal, Konsole, Alacritty) are not auto-detected. Set `SWARMFORGE_TERMINAL=none` explicitly or contribute a Linux adapter to the `terminal-adapters/` directory.

### What's the difference between `SWARMFORGE_TERMINAL` and `SWARMFORGE_TERMINAL_BACKEND`?

`SWARMFORGE_TERMINAL` controls the main SwarmForge session backend through `detect_terminal_backend`. `SWARMFORGE_TERMINAL_BACKEND` is consumed directly by helper utilities like [`swarm-cleanup.sh`](https://github.com/unclebob/swarm-forge/blob/main/swarm-cleanup.sh) with a hardcoded default of `terminal-app`. Use the primary variable for normal operation; use the secondary variable when cleanup scripts need different terminal targeting.