Terminal Sessions

Terminal Sessions

Kollab manages terminal sessions for you: start any command, keep it running in the background, and watch its live output without leaving your LLM chat interface. The /tmux aliases are kept for muscle memory; sessions no longer require tmux.

Overview

The terminal plugin manages sessions as isolated subprocesses with their output captured into a ring buffer, allowing you to:

  • Create terminal sessions - run any command in the background
  • Live session viewing - watch session output in real-time in a fullscreen view
  • Interactive passthrough - send keyboard input directly to sessions
  • Process isolation - each session runs in its own process group, separate from kollab

No tmux required: Sessions are managed subprocesses with captured output. The /tmux and /t aliases remain so existing habits keep working.

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>           View session (alias for view)

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 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

# View a specific session
/terminal attach devserver

Live Viewing

The live view provides a fullscreen, real-time view of session output. It runs on the AltView stack (TerminalAltView managed by the AltView stack manager).

Automatic Refresh

Output refreshes every half second by default (configurable) to show the latest content from the session.

Smart Viewport

The view adapts to terminal size to maximize visible content.

Session Cycling

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

Passthrough Input

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

Content Capture

The plugin captures each session's output into a ring buffer as it is produced and prepares it for display:

  • Keeps a configurable number of lines (default: 200)
  • Shows the newest content from the buffer
  • Removes trailing empty lines
  • Returns the newest lines that fit in the viewport

Plugin Architecture

TmuxPlugin Class

Located at plugins/terminal_plugin.py (with the viewer at plugins/terminal_altview.py), the plugin follows Kollab's standard plugin pattern.

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

    Despite the class name (kept for backward compat / plugin discovery),
    this no longer uses tmux. All sessions are subprocess.Popen instances
    with output captured into RingBuffer.
    """

    def __init__(self, name: str = "tmux", event_bus=None, renderer=None, config=None):
        self.sessions: Dict[str, TerminalSession] = {}

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

    async def execute_background(self, command, name=None, cwd=None):
        """Start a session running a command."""

    async def capture_session_output(self, name, lines=50):
        """Read the newest lines from the session ring buffer."""

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

TerminalSession Data Model

@dataclass
class TerminalSession:
    """Represents a managed terminal session backed by subprocess.Popen."""
    name: str                       # Session identifier
    command: str                    # Startup command
    proc: Optional[subprocess.Popen]
    ring_buffer: Optional[RingBuffer]
    pid: int                        # Process ID
    created_at: datetime

    def is_alive(self) -> bool:
        """Check if the subprocess 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>", "View session (alias for view)"),
    ],
)

Event Integration

The view command pushes a TerminalAltView onto the AltView stack; the stack manager owns rendering and input routing while the view is open, and the main render loop resumes when it closes.

Configuration

Configure the tmux plugin in ~/.kollab/config.json:

{
  "plugins": {
    "tmux": {
      "enabled": true,
      "show_status": true,
      "refresh_rate_ms": 500,
      "capture_lines": 200
    }
  }
}
OptionTypeDefaultDescription
plugins.tmux.enabledbooleantrueEnable the tmux plugin
plugins.tmux.show_statusbooleantrueShow session count in status bar
plugins.tmux.refresh_rate_msnumber500Live view refresh rate (milliseconds)
plugins.tmux.capture_linesnumber200Lines to capture from pane history

External Access

Sessions are kollab-managed subprocesses, so there is no separate tmux server to attach to from outside. Use /terminal view inside kollab to watch a session, or run your own tmux outside kollab when you need an external attach.

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