# How to Add a Custom Terminal Backend to SwarmForge: A Complete Guide

> Learn how to add a custom terminal backend to SwarmForge. Follow this complete guide to implement init_terminal and run_command functions for your new adapter.

- Repository: [Robert C. Martin/swarm-forge](https://github.com/unclebob/swarm-forge)
- Tags: how-to-guide
- Published: 2026-08-29

---

**To add a custom terminal backend to SwarmForge, create a new adapter script in `swarmforge/scripts/terminal-adapters/` that implements the `init_terminal()` and `run_command()` functions, then register it via the `SWARM_TERMINAL_ADAPTER` environment variable.**

SwarmForge uses a **terminal-adapter** mechanism to abstract away how commands are executed in terminal windows. This architecture lets you swap terminal emulators or even use remote consoles without modifying the core codebase. In this guide, you'll learn how to build and register a custom backend by examining the actual source code in `unclebob/swarm-forge`.

## Understanding the Terminal Adapter Architecture

The core loader [`swarmforge/scripts/swarm-terminal-adapter.sh`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/scripts/swarm-terminal-adapter.sh) discovers available adapters, selects one based on configuration, and sources the chosen script to run terminal commands. Each adapter is a self-contained shell script that lives in `swarmforge/scripts/terminal-adapters/`.

SwarmForge ships with several built-in adapters:

- [`none.sh`](https://github.com/unclebob/swarm-forge/blob/main/none.sh) — no-op fallback adapter
- [`windows-terminal.sh`](https://github.com/unclebob/swarm-forge/blob/main/windows-terminal.sh) — Windows Terminal support
- [`iterm2.sh`](https://github.com/unclebob/swarm-forge/blob/main/iterm2.sh) — iTerm2 on macOS

When you set `SWARM_TERMINAL_ADAPTER=my-adapter`, the loader looks for [`terminal-adapters/my-adapter.sh`](https://github.com/unclebob/swarm-forge/blob/main/terminal-adapters/my-adapter.sh) and sources it directly.

## Step 1: Create Your Custom Adapter Script

Create a new executable file in the terminal-adapters directory. The script must define two functions: `init_terminal` and `run_command`.

Here's a minimal custom adapter for Alacritty:

```bash
#!/usr/bin/env bash

# -------------------------------------------------

# Custom terminal adapter for SwarmForge

# -------------------------------------------------

# Called once when SwarmForge starts up.

init_terminal() {
  # Optional: set up environment variables, verify dependencies, etc.

  echo "[my-terminal] Initialising custom terminal backend"
  # Example: ensure the chosen terminal executable exists

  command -v alacritty >/dev/null || {
    echo "Error: alacritty not found – install it or adjust the adapter"
    exit 1
  }
}

# Called for every command that SwarmForge needs to run inside a terminal.

# Arguments: the command line to execute.

run_command() {
  local cmd="$*"
  echo "[my-terminal] Running: $cmd"
  # Launch the command inside Alacritty; --hold keeps the window open after exit.

  alacritty --hold -e bash -c "$cmd"
}

```

Save this as [`swarmforge/scripts/terminal-adapters/my-terminal.sh`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/scripts/terminal-adapters/my-terminal.sh) and make it executable:

```bash
chmod +x swarmforge/scripts/terminal-adapters/my-terminal.sh

```

## Step 2: Register the Custom Terminal Backend

Expose your adapter to SwarmForge by setting the `SWARM_TERMINAL_ADAPTER` environment variable. You have two options:

**Option A: Export before running SwarmForge**

```bash
export SWARM_TERMINAL_ADAPTER=my-terminal
swarmforge pack_web

```

**Option B: Add to [`swarmforge.conf`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge.conf)**

Edit [`swarmforge/swarmforge.conf`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/swarmforge.conf) and add:

```bash
export SWARM_TERMINAL_ADAPTER=my-terminal

```

This persists your choice across sessions.

## Step 3: Test Your Custom Terminal Integration

Verify the integration by running a SwarmForge command that spawns a terminal:

```bash
SWARM_TERMINAL_ADAPTER=my-terminal swarmforge pack_web

```

You should see:
- Your `init_terminal` output (if implemented)
- An Alacritty window opening
- The SwarmForge command executing inside that window
- The window remaining open after completion (due to `--hold`)

## Extending Your Custom Terminal Backend

Because [`swarm-terminal-adapter.sh`](https://github.com/unclebob/swarm-forge/blob/main/swarm-terminal-adapter.sh) simply sources your adapter script, you can embed any logic directly inside it:

- **Environment preparation** — set variables, activate virtual environments
- **UI tweaks** — configure terminal dimensions, colors, or themes
- **Remote execution** — tunnel commands through SSH to a remote host
- **Container integration** — launch commands inside Docker or Podman

Review [`swarmforge/scripts/terminal-adapters/iterm2.sh`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/scripts/terminal-adapters/iterm2.sh) for a production example with macOS-specific window management.

## Key Source Files in SwarmForge

| File | Purpose |
|------|---------|
| [`swarmforge/scripts/swarm-terminal-adapter.sh`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/scripts/swarm-terminal-adapter.sh) | Core loader that discovers and routes to adapters |
| [`swarmforge/scripts/terminal-adapters/none.sh`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/scripts/terminal-adapters/none.sh) | Built-in no-op fallback adapter |
| [`swarmforge/scripts/terminal-adapters/iterm2.sh`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/scripts/terminal-adapters/iterm2.sh) | Reference implementation for macOS iTerm2 |
| [`swarmforge/swarmforge.conf`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/swarmforge.conf) | Configuration file for adapter registration |

## Summary

- SwarmForge's terminal-adapter mechanism lives in `swarmforge/scripts/terminal-adapters/`
- Custom adapters require two functions: `init_terminal()` and `run_command()`
- Activate your backend by setting `SWARM_TERMINAL_ADAPTER` in environment or config
- The loader sources your script directly, enabling arbitrary customization
- Test with commands like `swarmforge pack_web` that trigger terminal spawning

## Frequently Asked Questions

### What terminal emulators work with SwarmForge custom backends?

Any terminal emulator that accepts a command to execute works. The adapter pattern is emulator-agnostic—you simply invoke your chosen terminal with its specific flags inside `run_command()`. Alacritty, Kitty, WezTerm, GNOME Terminal, and custom SSH-based consoles have all been used successfully.

### Where does SwarmForge look for terminal adapter scripts?

SwarmForge searches the `swarmforge/scripts/terminal-adapters/` directory relative to the installation. The core loader at [`swarmforge/scripts/swarm-terminal-adapter.sh`](https://github.com/unclebob/swarm-forge/blob/main/swarmforge/scripts/swarm-terminal-adapter.sh) constructs the path by appending your `SWARM_TERMINAL_ADAPTER` value plus `.sh` to this directory.

### Can a custom terminal backend run commands remotely?

Yes. Since the adapter script is sourced and executed directly, you can implement SSH tunneling, Docker exec, or any remote execution logic inside `run_command()`. The function receives the full command string as arguments, which you can wrap or forward as needed.

### What happens if my custom adapter fails to initialize?

If `init_terminal()` exits with a non-zero status, the failure propagates through the loader and SwarmForge aborts. Include dependency checks and clear error messages in your initialization code to diagnose issues early.