# 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` - `` - **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 ``` # Main app orchestrator ├── # Login form ├── # Session listing │ └── # Individual session ├── # Full-screen terminal │ ├── # xterm.js wrapper │ └── # Binary buffer renderer └── # 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): ```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: ```json [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] [args...]` **Options**: - `--session-id `: Use specific session ID - `--title-mode `: none|filter|static|dynamic - `--update-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 ```bash # 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**: ```bash # 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.