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 theSWARMFORGE_TERMINALenvironment variable or host capabilities (iTerm, macOS Terminal, Windows Terminal)normalize_terminal_backend– Maps user-friendly names (e.g.,iterm,terminal,wt) to exact adapter filenamesload_terminal_backend– Sources the adapter file fromswarmforge/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 purposesterminal_backend_can_open_sessions– Returns0if the backend can launch new tmux sessions, non-zero otherwiseterminal_backend_tracks_windows– Returns0if the backend can query existing windows (used for cleanup operations), non-zero otherwiseterminal_window_exists <window_id>– Returns0if the given window ID still existsterminal_open_session <session> <title>– Launches a new terminal window/tab, attaches the tmux session, and echoes the window IDterminal_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 inswarmforge/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, andterminal_close_window - Adapter scripts must be executable Zsh files placed in the terminal-adapters directory
- Activate custom backends using the
SWARMFORGE_TERMINALenvironment variable set to the script name without the.shextension - Reference built-in adapters like
terminal-app.shandnone.shfor 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →