Tmux Integration

Kollab CLI includes a powerful tmux plugin for managing terminal sessions, viewing live output, and running background commands without leaving your LLM chat interface.

Overview

The TmuxPlugin provides seamless integration with the tmux terminal multiplexer, allowing you to:

  • Create tmux sessions - spawn detached sessions running any command
  • Live session viewing - watch session output in real-time with a fullscreen modal
  • Interactive passthrough - send keyboard input directly to sessions
  • Isolated server mode - dedicated tmux server prevents conflicts with your main sessions

Default Behavior: Sessions use a dedicated tmux server (tmux -L kollabor) that is completely isolated from your main tmux sessions. This prevents name conflicts and keeps your workflow clean.

The /terminal Command

The main interface for tmux integration is the /terminal slash command with several aliases.

Aliases: /terminal, /tmux, /term, /t

Subcommands:
  new <name> <command>    Create new session running command
  view [name]             Live view session (Opt+Left/Right to cycle)
  list                    List all sessions
  kill <name>             Kill a session
  attach <name>           Show attach command for external tmux

Creating Sessions

# Start a development server
/terminal new devserver npm run dev

# Follow log files
/terminal new logs tail -f /var/log/app.log

# Run a Python web server
/t new webserver python -m http.server 8080

# Start a background build watcher
/term new build npm run watch

Viewing Sessions

The view subcommand opens a fullscreen live modal showing session output that refreshes automatically.

# View first available session
/t

# View first available session (explicit)
/t view

# View specific session
/terminal view devserver
Keyboard ShortcutAction
EscapeExit live view
Opt+Left / Opt+RightCycle between sessions
Opt+Up / Opt+DownPage up/down in session
Opt+xKill current session and exit
Arrow keysForward to tmux session
Ctrl+CSend interrupt to session
Text inputForward to session

Managing Sessions

# List all sessions (managed and discovered)
/t list
/t ls

# Kill a specific session
/terminal kill devserver

# Get attach command for external use
/terminal attach devserver

Live Modal Viewing

The live modal provides a fullscreen, real-time view of tmux session output. It's powered by the LiveModalConfig system and uses the LIVE_MODAL_TRIGGER event.

Automatic Refresh

Output refreshes every 2 seconds (configurable) to show the latest content from the tmux pane.

Smart Viewport

Modal height adapts to terminal size (terminal height - 8 lines) to maximize visible content.

Session Cycling

Navigate between multiple sessions without closing the modal using Opt+Left/Right arrows.

Passthrough Input

All keyboard input is forwarded to the active tmux session for interactive control.

Content Capture

The plugin captures session output using tmux capture-pane and processes it for display:

  • Strips ANSI color codes for clean display
  • Captures configurable number of lines (default: 200)
  • Shows newest content from bottom of pane history
  • Removes trailing empty lines
  • Returns newest lines that fit in viewport

Plugin Architecture

TmuxPlugin Class

Located at plugins/tmux_plugin.py, the plugin follows Kollabor's standard plugin pattern.

class TmuxPlugin:
    """Plugin for tmux session management and live viewing."""

    def __init__(self, name, event_bus, renderer, config):
        self.sessions: Dict[str, TmuxSession] = {}
        self._current_session: Optional[str] = None

    async def initialize(self, event_bus, config, **kwargs):
        """Register commands and discover existing sessions."""

    def _tmux_cmd(self, *args) -> List[str]:
        """Build tmux command with socket configuration."""

    def _capture_tmux_pane(self, session_name, max_lines) -> List[str]:
        """Capture current content of a tmux pane."""

    def _send_keys_to_tmux(self, session_name, keys):
        """Send keys to a tmux session."""

    def _cycle_session(self, forward=True) -> Optional[str]:
        """Cycle to next/previous tmux session."""

TmuxSession Data Model

@dataclass
class TmuxSession:
    """Represents a managed tmux session."""
    name: str                  # Session identifier
    command: str               # Startup command
    tmux_cmd: callable         # Command builder with socket
    created_at: datetime       # Creation timestamp
    pid: Optional[int]         # Process ID

    def is_alive(self) -> bool:
        """Check if the tmux session is still running."""

Command Registration

The plugin registers with the CommandRegistry during initialization:

terminal_cmd = CommandDefinition(
    name="terminal",
    description="Manage terminal sessions (new/view/list/kill)",
    handler=self._handle_tmux_command,
    plugin_name="tmux",
    category=CommandCategory.CUSTOM,
    mode=CommandMode.INSTANT,
    aliases=["term", "tmux", "t"],
    icon="[>_]",
    subcommands=[
        SubcommandInfo("new", "<name> <cmd>", "Create session running command"),
        SubcommandInfo("view", "[name]", "Live view session (default)"),
        SubcommandInfo("list", "", "List all sessions"),
        SubcommandInfo("kill", "<name>", "Kill a session"),
        SubcommandInfo("attach", "<name>", "Attach (exits kollabor)"),
    ],
)

Event Integration

The view command emits a LIVE_MODAL_TRIGGER event to activate the live modal:

# Configure the live modal
config = LiveModalConfig(
    title="terminal",
    footer="Esc: exit | Opt+Left/Right: cycle | Opt+Up/Down: page | Opt+x: kill",
    refresh_rate=2.0,  # 2 seconds
    passthrough_input=True,
)

# Emit event to trigger live modal
await self.event_bus.emit_with_hooks(
    EventType.LIVE_MODAL_TRIGGER,
    {
        "content_generator": get_tmux_content,
        "config": config,
        "input_callback": handle_input,
    },
    "live_modal",
)

Configuration

Configure the tmux plugin in ~/.kollabor-cli/config.json:

{
  "terminal": {
    "timeout": 90,
    "tmux_server": null,
    "use_separate_server": true,
    "kill_on_shutdown": false,
    "capture_lines": 200,
    "refresh_rate": 2.0
  },
  "plugins": {
    "tmux": {
      "enabled": true,
      "show_status": true,
      "refresh_rate": 0.5,
      "capture_lines": 200,
      "use_separate_server": true,
      "socket_name": null
    }
  }
}
OptionTypeDefaultDescription
terminal.timeoutnumber90Default timeout for terminal commands (seconds)
terminal.tmux_serverstringnullSocket name (null = use project folder name)
terminal.use_separate_serverbooleantrueUse dedicated tmux server
terminal.capture_linesnumber200Number of lines to capture from pane history
terminal.refresh_ratenumber2.0Live view refresh rate (seconds)
plugins.tmux.enabledbooleantrueEnable the tmux plugin
plugins.tmux.show_statusbooleantrueShow session count in status bar

External Access

When using the default separate server mode, you can interact with Kollabor tmux sessions from your terminal.

With Separate Server (Default)

# List kollabor sessions
tmux -L kollabor list-sessions

# Attach to a session
tmux -L kollabor attach -t devserver

# Kill a session
tmux -L kollabor kill-session -t devserver

# Create external session on kollabor server
tmux -L kollabor new-session -s external-session

Using Main Tmux Server

Disable separate server in config to use your main tmux server:

{
  "terminal": {
    "use_separate_server": false
  }
}

Then use standard tmux commands without the -L flag.

Public API

The TmuxPlugin exposes several public methods for ToolExecutor integration and programmatic access:

# Execute command in temporary session (foreground)
async def execute_foreground(
    command: str,
    timeout: int = 90,
    cwd: str = None
) -> Dict[str, Any]:
    """Returns: {success, output, error, exit_code}"""

# Execute command in persistent session (background)
async def execute_background(
    command: str,
    name: str = None,
    timeout: str = None,
    cwd: str = None
) -> Dict[str, Any]:
    """Returns: {success, session_name, message}"""

# Get session status
async def get_session_status(name: str) -> Dict[str, Any]:
    """Use "*" for all sessions"""

# Capture session output
async def capture_session_output(
    name: str,
    lines: int = 50
) -> Dict[str, Any]:
    """Returns: {success, output, message}"""

# Kill background session
async def kill_background_session(
    name: str,
    signal: str = "SIGTERM"
) -> Dict[str, Any]:
    """Use "*" to kill all managed sessions"""

Common Use Cases

Development Servers

Run dev servers in the background while chatting with your LLM.

/t new devserver npm run dev

Log Monitoring

Follow log files and view them in real-time when needed.

/t new logs tail -f /var/log/app.log

Build Watchers

Run build tools that watch for file changes.

/t new build npm run watch

Long-Running Scripts

Execute scripts that take time without blocking your chat.

/t new migration python manage.py migrate

Database Connections

Keep database CLI sessions open for quick queries.

/t new db psql -U user -d myapp