VibeTunnel Web Architecture Specification

This document provides a comprehensive map of the VibeTunnel web application architecture, including server components, client structure, API specifications, and protocol details. Updated: 2025-07-01

Key Files Quick Reference

Server Core

  • Entry Point: src/server/server.ts:912 - startVibeTunnelServer()
  • App Creation: src/server/server.ts:330 - createApp()
  • Configuration: src/server/server.ts:57 - Config interface
  • CLI Entry: src/server/cli.ts:51-56 - vibetunnel fwd command

Authentication

  • Service: src/server/services/auth-service.ts:144-271 - SSH key verification
  • Middleware: src/server/middleware/auth.ts:20-105 - JWT validation
  • Routes: src/server/routes/auth.ts:20-178 - Auth endpoints

Session Management

  • PTY Manager: src/server/pty/pty-manager.ts:57 - Session Map
  • Session Manager: src/server/pty/session-manager.ts:40-141 - Session lifecycle
  • Routes: src/server/routes/sessions.ts:134-1252 - Session API

Real-time Communication

  • Binary Buffer: src/server/services/terminal-manager.ts:378-574 - Buffer encoding
  • WebSocket Server: src/server/services/buffer-aggregator.ts:44-344 - Buffer streaming
  • Input Handler: src/server/routes/websocket-input.ts:156-164 - Input protocol

Client Core

  • Entry Point: src/client/app-entry.ts:1-28 - App initialization
  • Main Component: src/client/app.ts:44-1355 - <vibetunnel-app>
  • Terminal: src/client/components/terminal.ts:23-1567 - xterm.js wrapper

Server Architecture

Main Server (src/server/server.ts)

The server provides a comprehensive API for terminal session management with support for distributed deployments. Configuration Options:
  • port: Server port (default: 4020)
  • bind: Bind address (default: 127.0.0.1)
  • isHQMode: Run as headquarters server
  • hqUrl/hqUsername/hqPassword: Remote server registration
  • enableSSHKeys: Enable SSH key authentication
  • noAuth: Disable all authentication
Key Services:
  • Authentication (JWT + SSH keys)
  • Session management (PTY processes)
  • WebSocket communication (binary buffers + input)
  • File system operations
  • Push notifications
  • Activity monitoring

Authentication System

Supported Methods:
  1. SSH Key Authentication (src/server/routes/auth.ts:52)
    • Challenge-response with Ed25519 signatures
    • Verifies against ~/.ssh/authorized_keys
  2. Password Authentication (src/server/routes/auth.ts:101)
    • PAM authentication or environment variables
  3. Bearer Token (HQ mode)
    • For server-to-server communication
  4. Local Bypass (optional)
    • Localhost connections with optional token
JWT Token Flow:
  1. Client requests challenge from /api/auth/challenge
  2. Server generates random challenge
  3. Client signs challenge and sends to /api/auth/ssh-key
  4. Server verifies signature and returns JWT token

Session Management

Session Lifecycle:
  1. Creation (src/server/routes/sessions.ts:134):
    • Spawns PTY process using node-pty
    • Creates session directory in ~/.vibetunnel/control/
    • Saves metadata to session.json
  2. Tracking:
    • In-memory: PtyManager.sessions Map
    • On-disk: Session directories with stdout/stdin files
  3. Cleanup (src/server/pty/session-manager.ts:297):
    • Automatic cleanup of exited sessions
    • 5-minute cleanup interval
    • Zombie process detection
Control Directory Structure:
~/.vibetunnel/control/
├── [sessionId]/
│   ├── session.json    # Session metadata
│   ├── stdout          # Terminal output
│   ├── stdin           # Terminal input log
│   ├── activity.json   # Activity status
│   └── ipc.sock        # Unix socket for IPC

Client Architecture

Component Hierarchy

<vibetunnel-app>                  # Main app orchestrator
├── <auth-login>                  # Login form
├── <session-list>                # Session listing
│   └── <session-card>           # Individual session
├── <session-view>               # Full-screen terminal
│   ├── <vibe-terminal>         # xterm.js wrapper
│   └── <vibe-terminal-buffer>  # Binary buffer renderer
└── <unified-settings>           # Settings panel

State Management

  • Component-level state using LitElement’s @state() decorator
  • localStorage for persistent data (auth tokens, preferences)
  • Event-driven communication between components
  • No global state management library

Services

AuthClient (src/client/services/auth-client.ts):
  • Manages authentication state
  • Handles SSH key and password auth
  • Stores tokens in localStorage
BufferSubscriptionService (src/client/services/buffer-subscription-service.ts):
  • WebSocket connection for binary terminal buffers
  • Automatic reconnection with exponential backoff
  • Multiplexed subscriptions per session
WebSocketInputClient (src/client/services/websocket-input-client.ts):
  • Low-latency input transmission
  • Fire-and-forget protocol
  • Per-session connections

API Specification

REST Endpoints

Sessions

  • GET /api/sessions - List all sessions
  • POST /api/sessions - Create new session
  • GET /api/sessions/:id - Get session info
  • DELETE /api/sessions/:id - Kill session
  • POST /api/sessions/:id/input - Send input
  • POST /api/sessions/:id/resize - Resize terminal
  • GET /api/sessions/:id/stream - SSE output stream
  • GET /api/sessions/:id/text - Get text output
  • GET /api/sessions/:id/buffer - Get binary buffer
  • GET /api/sessions/activity - Get all activity

Authentication

  • POST /api/auth/challenge - Request challenge
  • POST /api/auth/ssh-key - SSH key auth
  • POST /api/auth/password - Password auth
  • GET /api/auth/verify - Verify token
  • GET /api/auth/config - Get auth config

HQ Mode (Distributed)

  • GET /api/remotes - List remote servers
  • POST /api/remotes/register - Register remote
  • DELETE /api/remotes/:id - Unregister remote

Git Integration

  • GET /api/worktrees - List worktrees
  • POST /api/worktrees - Create worktree
  • POST /api/worktrees/follow - Enable/disable follow mode
  • GET /api/worktrees/follow - Get follow mode status
  • POST /api/git/events - Git hook notifications

WebSocket Protocols

Binary Buffer Protocol (/buffers)

Connection: WebSocket with Bearer token authentication Client → Server Messages (JSON):
{ "type": "subscribe", "sessionId": "session_123" }
{ "type": "unsubscribe", "sessionId": "session_123" }
{ "type": "ping" }
Server → Client Messages (Binary):
[0xBF][ID Length (4 bytes)][Session ID (UTF-8)][Buffer Data]
Buffer Data Format (32-byte header + cells):
Header (32 bytes):
├── Magic: 0x5654 "VT" (2 bytes)
├── Version: 0x01 (1 byte)
├── Flags: reserved (1 byte)
├── Columns (4 bytes)
├── Rows (4 bytes)
├── ViewportY (4 bytes)
├── CursorX (4 bytes)
├── CursorY (4 bytes)
└── Reserved (4 bytes)

Row Encoding:
├── Empty rows: [0xFE][count]
└── Content rows: [0xFD][cell count (2 bytes)][cells...]

Cell Type Byte:
├── Bit 7: Has extended data
├── Bit 6: Is Unicode
├── Bit 5: Has foreground color
├── Bit 4: Has background color
├── Bit 3: Is RGB foreground
├── Bit 2: Is RGB background
└── Bits 1-0: Character type (00=space, 01=ASCII, 10=Unicode)

Input Protocol (/ws/input)

Connection: ws://host/ws/input?sessionId=X&token=Y Message Format:
  • Regular text: Sent as-is
  • Special keys: \x00key_name\x00

Server-Sent Events (SSE)

Session Output Stream (/api/sessions/:id/stream) Uses asciinema cast v2 format:
[timestamp, "o", "output text"]      // Terminal output
[timestamp, "i", "input text"]       // User input
[timestamp, "r", "80x24"]           // Resize event
["exit", exitCode, sessionId]       // Process exit

fwd.ts Application

The fwd.ts tool (src/server/fwd.ts) wraps any command in a VibeTunnel session: Usage: pnpm exec tsx src/fwd.ts [options] <command> [args...] Options:
  • --session-id <id>: Use specific session ID
  • --title-mode <mode>: none|filter|static|dynamic
  • --update-title <title>: Update existing session title
Features:
  • Auto-detects Claude AI and enables dynamic titles
  • Forwards stdin/stdout through PTY infrastructure
  • Creates sessions accessible via web interface
  • Activity detection for intelligent status updates
Socket Protocol (src/server/pty/socket-protocol.ts):
Message Types:
├── stdin: { type: 'stdin', data: Buffer }
├── resize: { type: 'resize', cols: number, rows: number }
├── kill: { type: 'kill', signal?: string }
└── status: { type: 'status', message: string }

HQ Mode & Distributed Architecture

Remote Registration

  1. Remote servers register with HQ using bearer tokens
  2. HQ maintains registry of all remote servers
  3. Health checks every 15 seconds
  4. Automatic session discovery

Request Routing

  • HQ checks session ownership via registry
  • Forwards API requests to appropriate remote
  • Proxies SSE streams transparently
  • Multiplexes WebSocket connections

High Availability

  • Graceful degradation on remote failure
  • Continues serving local sessions
  • Automatic reconnection for WebSocket streams
  • Session ownership tracking for reliability

Activity Tracking

Activity Monitor (src/server/services/activity-monitor.ts)

  • Monitors stdout file changes (100ms intervals)
  • Marks sessions inactive after 500ms of no output
  • Persists activity to activity.json
  • Provides real-time activity status

Activity Detection (src/server/utils/activity-detector.ts)

  • App-specific status detection (Claude AI)
  • Filters prompt-only output
  • Dynamic title updates based on activity
  • 5-second activity timeout

Additional Features

Push Notifications

  • Web Push API with VAPID authentication
  • Bell event notifications from terminal
  • Service worker for offline support
  • Process context in notifications

File Browser

  • Full filesystem browsing with Git status
  • Monaco Editor for code preview
  • Git diff visualization
  • Image preview support

SSH Key Management

  • Browser-based Ed25519 key generation
  • Import/export functionality
  • Password-protected key support
  • Web Crypto API integration

Native Terminal Spawning (macOS)

  • Unix socket at /tmp/vibetunnel-terminal.sock
  • Requests native Terminal.app windows
  • Falls back to web terminal

Performance Optimizations

  • Binary buffer compression (empty row encoding)
  • Fire-and-forget input protocol
  • Debounced buffer notifications (50ms)
  • Efficient cell encoding with bit-packing

Development Commands

# Web directory commands
cd web/

# Development (auto-rebuild)
pnpm run dev

# Code quality (must run before commit)
pnpm run check         # Run all checks in parallel
pnpm run check:fix     # Auto-fix issues

# Individual commands
pnpm run lint          # ESLint
pnpm run format        # Prettier
pnpm run typecheck     # TypeScript

Git Follow Mode

Git follow mode creates an intelligent synchronization between a main repository and a specific worktree, enabling seamless development workflows where agents work in worktrees while developers maintain their IDE and server setups in the main repository. Key Components:
  • Git Hooks (src/server/utils/git-hooks.ts): Manages post-commit, post-checkout, post-merge hooks
  • Git Event Handler (src/server/routes/git.ts:186-482): Processes git events and handles synchronization
  • Socket API (src/server/api-socket-server.ts:217-267): Socket-based follow mode control
  • CLI Integration (web/bin/vt): Smart command handling with path/branch detection
Configuration:
  • Single config option: vibetunnel.followWorktree stores the worktree path being followed
  • Config is stored in the main repository’s .git/config
  • Follow mode is active when this config contains a valid worktree path
Synchronization Behavior:
  1. Worktree → Main (Primary): Branch switches, commits, and checkouts sync to main repo
  2. Main → Worktree (Limited): Only commits sync; branch switches auto-unfollow
  3. Auto-unfollow: Switching branches in main repo disables follow mode
Command Usage:
# From worktree - follow this worktree
vt follow

# From main repo - smart detection
vt follow                    # Follow current branch's worktree (if exists)
vt follow feature/new-api    # Follow worktree for this branch
vt follow ~/project-feature  # Follow worktree by path
Hook Installation:
  • Hooks installed in BOTH main repository and worktree
  • Hooks execute vt git event which notifies server via socket API
  • Server processes events based on source (main vs worktree)
  • Existing hooks are preserved with .vtbak extension
Event Flow:
  1. Git event occurs (checkout, commit, merge)
  2. Hook executes vt git event
  3. CLI sends event via socket to server
  4. Server determines sync action based on event source
  5. Appropriate git commands executed to maintain sync

Architecture Principles

  1. Modular Design: Clear separation between auth, sessions, and real-time communication
  2. Scalability: Horizontal scaling via HQ mode and remote servers
  3. Reliability: Automatic reconnection, health checks, graceful degradation
  4. Performance: Binary protocols, compression, minimal latency
  5. Security: Multiple auth methods, JWT tokens, secure WebSocket connections
For implementation details, refer to the line numbers provided in the Key Files Quick Reference section.