How to Add a Custom Terminal Backend to SwarmForge: Complete Implementation Guide

Adding a custom terminal backend to SwarmForge requires creating a Zsh adapter script in swarmforge/scripts/terminal-adapters/ that implements six standard API functions, then selecting it via the SWARMFORGE_TERMINAL environment variable.

SwarmForge abstracts terminal handling through terminal adapters—modular Zsh scripts that enable integration with any terminal emulator or remote UI. If you need to support a custom terminal that isn't covered by built-in adapters like iTerm2 or Windows Terminal, you can add a custom terminal backend to SwarmForge by conforming to the adapter interface defined in the core loader.

Understanding the Terminal Adapter Architecture

The terminal abstraction layer lives in swarmforge/scripts/swarm-terminal-adapter.sh. This script provides three key functions that manage backend lifecycle:

  • detect_terminal_backend – Automatically selects a backend based on the SWARMFORGE_TERMINAL environment variable or host capabilities (iTerm, macOS Terminal, Windows Terminal)
  • normalize_terminal_backend – Maps user-friendly names (e.g., iterm, terminal, wt) to exact adapter filenames
  • load_terminal_backend – Sources the adapter file from swarmforge/scripts/terminal-adapters/<name>.sh

When SwarmForge initializes, it calls load_terminal_backend with the normalized backend name, which sources your custom script and makes its functions available to the session manager.

Required Terminal Adapter API

Every adapter must expose six public functions. SwarmForge calls these to manage terminal windows and tmux sessions:

  • terminal_backend_label – Returns a human-readable name for logging purposes
  • terminal_backend_can_open_sessions – Returns 0 if the backend can launch new tmux sessions, non-zero otherwise
  • terminal_backend_tracks_windows – Returns 0 if the backend can query existing windows (used for cleanup operations), non-zero otherwise
  • terminal_window_exists <window_id> – Returns 0 if the given window ID still exists
  • terminal_open_session <session> <title> – Launches a new terminal window/tab, attaches the tmux session, and echoes the window ID
  • terminal_close_window <window_id> – Closes the specific window identified by the ID

Reference implementations are available in the built-in adapters: terminal-app.sh (macOS Terminal) and none.sh (fallback no-op backend).

Step-by-Step: Creating a Custom Backend

1. Create the Adapter Script

Create a new file in swarmforge/scripts/terminal-adapters/ named after your backend (e.g., mybackend.sh). The file must be executable Zsh.

2. Implement the Required Functions

Below is a complete example implementing a GNOME Terminal adapter. This script opens new GNOME Terminal windows and attaches them to tmux sessions:

#!/usr/bin/env zsh

# File: swarmforge/scripts/terminal-adapters/mybackend.sh

terminal_backend_label() {
  echo "GNOME Terminal"
}

terminal_backend_can_open_sessions() {
  # Return 0 if gnome-terminal is available

  has_command gnome-terminal && return 0
  return 1
}

terminal_backend_tracks_windows() {
  # GNOME Terminal does not support reliable window querying

  return 1
}

terminal_window_exists() {
  # No tracking capability; assume window exists

  return 0
}

terminal_open_session() {
  local session="$1"
  local title="$2"
  
  # Launch GNOME Terminal, cd to working directory, and attach tmux

  gnome-terminal \
    --title="$title" \
    -- bash -c "cd \"$WORKING_DIR\" && exec tmux -S \"$TMUX_SOCKET\" attach-session -t \"$session\""
  
  # Echo placeholder ID since GNOME Terminal doesn't return window IDs

  echo "gnome-terminal"
}

terminal_close_window() {
  # No reliable method to close by ID; silently succeed

  return 0
}

Place this file at swarmforge/scripts/terminal-adapters/mybackend.sh and make it executable:

chmod +x swarmforge/scripts/terminal-adapters/mybackend.sh

3. Select Your Backend

Activate your custom backend by setting the environment variable before invoking SwarmForge:

export SWARMFORGE_TERMINAL=mybackend

SwarmForge will now load your adapter via load_terminal_backend "mybackend" and use your implementations for session management.

Note: Some legacy scripts in the codebase reference SWARMFORGE_TERMINAL_BACKEND (as seen in swarmforge/scripts/swarm-cleanup.sh), but the primary variable for new implementations is SWARMFORGE_TERMINAL.

Summary

  • SwarmForge loads terminal adapters from swarmforge/scripts/terminal-adapters/ via the loader in swarmforge/scripts/swarm-terminal-adapter.sh
  • Custom backends must implement six standard functions: terminal_backend_label, terminal_backend_can_open_sessions, terminal_backend_tracks_windows, terminal_window_exists, terminal_open_session, and terminal_close_window
  • Adapter scripts must be executable Zsh files placed in the terminal-adapters directory
  • Activate custom backends using the SWARMFORGE_TERMINAL environment variable set to the script name without the .sh extension
  • Reference built-in adapters like terminal-app.sh and none.sh for implementation patterns

Frequently Asked Questions

What programming language must I use for the adapter script?

You must write terminal adapters in Zsh. The SwarmForge loader sources these scripts directly into the main Zsh environment, so they must be compatible with Zsh syntax and have access to the shell functions and variables defined by the core system.

Where does SwarmForge look for adapter files?

SwarmForge loads adapters from the swarmforge/scripts/terminal-adapters/ directory relative to the repository root. The load_terminal_backend function constructs the path by appending the backend name and .sh extension to this directory.

Can I use environment variables within my adapter script?

Yes. Your adapter has access to SwarmForge's internal variables including $WORKING_DIR and $TMUX_SOCKET, which you should use when launching terminal sessions to ensure proper tmux attachment and directory context.

How do I handle terminals that cannot track window IDs?

If your terminal emulator cannot reliably track or query window IDs (like GNOME Terminal), implement terminal_backend_tracks_windows to return 1 (false) and terminal_window_exists to always return 0. This tells SwarmForge to skip window cleanup operations for your backend, as demonstrated in the none.sh fallback adapter.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →