Skip to main content
The Web terminal plugin provides browser-based terminal access to agent sessions using xterm.js. Unlike iTerm2, it doesn’t directly open terminals but generates URLs for the web dashboard to render terminal interfaces.

Overview

The Web terminal plugin provides:
  • Cross-platform terminal access (any OS)
  • Browser-based xterm.js interface
  • URL generation for dashboard terminal pages
  • Session open state tracking
  • No external dependencies
  • Remote access capability
The Web terminal plugin is platform-agnostic and works on any operating system with a web browser.

How It Works

The Web terminal plugin is passive compared to iTerm2:
  1. URL Generation: Creates dashboard URLs for terminal access
  2. State Tracking: Tracks which sessions have been “opened”
  3. Console Logging: Outputs URLs for manual access
  4. Dashboard Integration: Web dashboard uses session runtime info for actual terminal connection
The plugin doesn’t open browser windows automatically. It logs URLs that you can open manually or that the dashboard can detect.

Configuration

Add the Web terminal plugin to your agent-orchestrator.yaml:
plugins:
  terminal:
    name: web
    config:
      dashboardUrl: http://localhost:3000  # Optional

Configuration Options

dashboardUrl
string
default:"http://localhost:3000"
Base URL for the web dashboard. Used to generate terminal page URLs.Examples:
  • Local development: http://localhost:3000
  • Remote server: https://orchestrator.example.com
  • Custom port: http://localhost:8080

URL Format

The plugin generates two types of URLs:

Single Session Terminal

http://localhost:3000/sessions/{session-id}/terminal
Example:
ao open my-session-id
# Logs: [terminal-web] Session my-session-id terminal available at
#       http://localhost:3000/sessions/my-session-id/terminal

All Sessions Page

http://localhost:3000/sessions
Example:
ao open --all
# Logs: [terminal-web] 5 sessions available at
#       http://localhost:3000/sessions

Dashboard Integration

The Web terminal plugin works with the Agent Orchestrator web dashboard: Dashboard Setup:
  1. Start the web server:
    cd packages/web
    pnpm dev
    
  2. Navigate to session page:
    http://localhost:3000/sessions/{session-id}/terminal
    
  3. Dashboard uses xterm.js to connect to the session’s runtime
Connection Flow:
  1. Dashboard reads session metadata
  2. Extracts runtimeHandle attachment info
  3. Creates xterm.js terminal instance
  4. Connects to runtime (e.g., tmux session via WebSocket proxy)
The dashboard handles the actual terminal connection. The plugin only tracks session open state and generates URLs.

Usage Examples

Local Development

plugins:
  terminal:
    name: web
    # Uses default: http://localhost:3000
Usage:
ao open my-session
# Open browser to: http://localhost:3000/sessions/my-session/terminal

Remote Server

plugins:
  terminal:
    name: web
    config:
      dashboardUrl: https://orchestrator.example.com
Usage:
ao open my-session
# Access from anywhere:
# https://orchestrator.example.com/sessions/my-session/terminal

Custom Port

plugins:
  terminal:
    name: web
    config:
      dashboardUrl: http://localhost:8080

Multi-Environment

projects:
  - name: local-dev
    plugins:
      terminal:
        name: web
        config:
          dashboardUrl: http://localhost:3000
  
  - name: staging
    plugins:
      terminal:
        name: web
        config:
          dashboardUrl: https://staging.orchestrator.example.com
  
  - name: production
    plugins:
      terminal:
        name: web
        config:
          dashboardUrl: https://orchestrator.example.com

Session State Tracking

The plugin tracks which sessions have been “opened”:
const openSessions = new Set<string>();

await terminal.openSession(session);
// Adds session.id to openSessions

const isOpen = await terminal.isSessionOpen(session);
// Returns: true if session.id in openSessions
State tracking is in-memory only. Restarting the orchestrator clears the open state.

Browser-Based Terminal

The web dashboard uses xterm.js for terminal rendering: Features:
  • Full ANSI color support
  • Copy/paste (browser-dependent)
  • Resizable terminal
  • Mouse support
  • Keyboard shortcuts
  • UTF-8 character support
Keyboard Shortcuts (default xterm.js):
  • Copy: Ctrl+Shift+C (or Cmd+C on macOS)
  • Paste: Ctrl+Shift+V (or Cmd+V on macOS)
  • Clear: Ctrl+L
  • Search: Ctrl+Shift+F
Keyboard shortcuts may vary based on browser and xterm.js addons. Check the dashboard documentation for the full list.

Remote Access

The Web terminal plugin enables remote access to agent sessions: Scenario: Agent runs on server, you access from laptop
  1. Deploy orchestrator on server:
    # On server (e.g., orchestrator.example.com)
    ao start
    cd packages/web && pnpm start  # Port 3000
    
  2. Configure plugin:
    plugins:
      terminal:
        name: web
        config:
          dashboardUrl: https://orchestrator.example.com
    
  3. Access from anywhere:
    # On laptop
    ssh orchestrator.example.com
    ao open my-session
    # Open laptop browser to URL
    
Security Considerations:
  • Use HTTPS for remote dashboards
  • Implement authentication (not included in base dashboard)
  • Use VPN or SSH tunneling for sensitive sessions
  • Restrict dashboard port access with firewall rules

Troubleshooting

Check dashboard is running:
curl http://localhost:3000/api/health
Verify session exists:
ao list
# Should show session with RUNNING status
Check browser console:
  • Open DevTools (F12)
  • Look for xterm.js errors
  • Verify WebSocket connection
Check runtime attachment info:
cat ~/.ao/sessions/{session-id}/metadata.txt
# Look for runtimeHandle data
Verify runtime is accessible:
  • For tmux: tmux ls should show session
  • For docker: container should be running
Check dashboard logs:
cd packages/web
pnpm dev
# Watch for connection errors
Update config:
plugins:
  terminal:
    name: web
    config:
      dashboardUrl: http://correct-url:3000
Verify environment:
ao config show
# Check terminal plugin config
Browser focus issues:
  • Click inside terminal area
  • Check browser doesn’t have conflicting shortcuts
  • Try different browser
xterm.js not initialized:
  • Refresh page
  • Check browser console for errors
  • Verify xterm.js loaded successfully
Browser security restrictions:
  • Use keyboard shortcuts: Ctrl+Shift+C/V
  • Some browsers require HTTPS for clipboard access
  • Check browser clipboard permissions
Alternative: Use iTerm2 plugin for native copy/paste if on macOS.

Comparison with iTerm2

FeatureWebiTerm2
PlatformAny OSmacOS only
SetupBrowser onlyiTerm2 required
Remote access✅ Native❌ Local only
PerformanceGood (JavaScript)Excellent (native)
Copy/pasteBrowser-dependentNative
CustomizationCSS/JSiTerm2 profiles
Tab managementBrowser tabsNative tabs
Keyboard shortcutsxterm.jsiTerm2 bindings
AuthenticationCustomOS-level

Use Cases

Perfect for:
  • CI/CD server with orchestrator
  • Shared development server
  • Team collaboration on agent sessions
  • Accessing sessions from any device
Perfect for:
  • Linux development machine
  • Windows + WSL
  • Docker-based workflows
  • Any non-macOS environment
Perfect for:
  • Screen sharing agent sessions
  • Client demonstrations
  • Training sessions
  • Recording terminal sessions
Perfect for:
  • Chromebook or thin client access
  • Tablet/mobile access (with caveats)
  • Kiosk mode displays
  • Embedded terminal in other web apps

Source Code

View the plugin source:
  • Package: @composio/ao-plugin-terminal-web
  • Location: packages/plugins/terminal-web/src/index.ts
  • Dashboard: packages/web/app/sessions/[id]/terminal/page.tsx

Build docs developers (and LLMs) love