VibeTunnel Technical Specification
Table of Contents
- Executive Summary
- System Architecture
- Data Flows
- Core Components
- Server Implementation
- Web Frontend
- iOS Application
- Security Model
- Session Management
- CLI Integration
- API Specifications
- Binary Buffer Protocol
- User Interface
- Configuration System
- Build and Release
- Testing Strategy
- Performance Requirements
- Error Handling
- Update System
- Platform Integration
- Data Formats
Executive Summary
Project Overview
VibeTunnel is a macOS application that provides browser-based access to Mac terminals, designed to make terminal access as simple as opening a web page. The project specifically targets developers and engineers who need to monitor AI agents (like Claude Code) remotely.Key Features
- Zero-Configuration Terminal Access: Launch terminals with a simple
vt
command - Browser-Based Interface: Access terminals from any modern web browser
- Real-Time Streaming: Live terminal updates via WebSocket with binary buffer optimization
- Session Recording: Full asciinema format recording support
- Security Options: Password protection, localhost-only mode, Tailscale/ngrok integration
- High-Performance Server: Node.js server with Bun runtime for optimal JavaScript performance
- Auto-Updates: Sparkle framework integration for seamless updates
- AI Agent Integration: Special support for Claude Code with shortcuts
- iOS Companion App: Mobile terminal access from iPhone/iPad
Technical Stack
- Native macOS App: Swift 6.0, SwiftUI, macOS 14.0+
- iOS App: Swift 6.0, SwiftUI, iOS 17.0+
- Server: Node.js/TypeScript with Bun runtime
- Web Frontend: TypeScript, Lit Web Components, Tailwind CSS
- Terminal Emulation: xterm.js with custom buffer optimization
- Build System: Xcode, Swift Package Manager, npm/Bun
- Distribution: Signed/notarized DMG with Sparkle updates
System Architecture
High-Level Architecture
Component Interaction Flow
- Terminal Launch: User executes
vt
command - Server Check: ServerManager ensures Bun server is running
- Session Creation: HTTP POST to create new terminal session
- PTY Allocation: Server allocates pseudo-terminal via node-pty
- WebSocket Upgrade: Client establishes WebSocket connection
- Binary Buffer Protocol: Optimized terminal data streaming
- Recording: Session data recorded in asciinema format
- Session Cleanup: Resources freed on terminal exit
Design Principles
- Single Server Implementation: One Node.js/Bun server handles everything
- Protocol-Oriented Swift: Clean interfaces between macOS components
- Binary Optimization: Custom buffer protocol for efficient terminal streaming
- Thread Safety: Swift actors and Node.js event loop for concurrent safety
- Minimal Dependencies: Only essential third-party libraries
- User Privacy: No telemetry or user tracking
Data Flows
Terminal Session Lifecycle
- User launches the
vt
command or selects New Session from the UI. ServerManager
verifies that the Bun server is running and starts it if needed.- A
POST /api/sessions
request triggersTerminalManager.createTerminal()
on the server. PtyManager.spawn()
allocates a new PTY process and stores session metadata.- The server responds with the session ID and WebSocket URL.
- Clients connect to
/api/sessions/:id/ws
and begin streaming using the binary buffer protocol. - Terminal output and input are recorded in asciinema format when recording is enabled.
- On process exit, resources are cleaned up and the client is notified.
Terminal I/O Flow
- Keyboard input from the browser or iOS app is sent as JSON messages over the WebSocket.
BufferAggregator
forwards the input to the PTY process.- PTY output is captured, aggregated and sent back as binary snapshots or text deltas.
- The client updates its terminal display accordingly.
Server Lifecycle Flow
- Starting the macOS app or running
vt
launchesServerManager
. BunServer
spawns the Bun-based HTTP/WebSocket server process.- Health checks hit
/api/health
to verify the server is alive. - On stop or crash,
ServerManager
gracefully shuts down or restarts the process.
Remote Access Flow
- When network mode is enabled, the server binds to
0.0.0.0
for remote access. NgrokService
or Tailscale can expose a secure public URL.- Remote clients reach the server through the tunnel and communicate over HTTPS.
Authentication Flow
- Clients request the dashboard or a session endpoint.
- Basic Auth middleware checks credentials stored via
DashboardKeychain
. - Local bypass or token-based headers are honored if configured.
- Successful authentication allows API and WebSocket communication.
Core Components
ServerManager
Location:mac/VibeTunnel/Core/Services/ServerManager.swift
Responsibilities:
- Manages Bun server process lifecycle (start/stop/restart)
- Handles server configuration (port, bind address)
- Provides log streaming from server process
- Coordinates with other services (Ngrok, SessionMonitor)
- Manages server health checks
- Uses
@Observable
for SwiftUI integration @MainActor
ensures UI thread safety- Publishes server state changes
- Maintains server configuration in UserDefaults
BunServer
Location:mac/VibeTunnel/Core/Services/BunServer.swift
Responsibilities:
- Spawns and manages the Bun executable process
- Handles process I/O streaming
- Monitors process health and auto-restarts
- Passes configuration via command-line arguments
- Embedded vibetunnel binary built with Bun
- Native PTY support via node-pty module
- Automatic crash recovery
- Log streaming to ServerManager
SessionMonitor
Location:mac/VibeTunnel/Core/Services/SessionMonitor.swift
Responsibilities:
- Polls server for active sessions
- Tracks session lifecycle
- Provides session counts for UI
- Handles session cleanup
- Real-time session tracking via polling
- Session metadata caching
- Automatic cleanup detection
- Performance monitoring
TerminalManager
Location:mac/VibeTunnel/Core/Services/TerminalManager.swift
Responsibilities:
- Integrates with macOS terminal applications
- Handles terminal app selection (Terminal.app, iTerm2, etc.)
- Manages AppleScript execution for terminal launching
- Provides terminal detection utilities
NgrokService
Location:mac/VibeTunnel/Core/Services/NgrokService.swift
Responsibilities:
- Manages ngrok tunnel lifecycle
- Provides secure public URLs
- Handles authentication token storage
- Monitors tunnel status
- API key management via Keychain
- Custom domain support
- Region selection
- Basic auth integration
Server Implementation
Node.js/Bun Server
Location:web/src/server/
directory
Architecture:
The server is built as a standalone Bun executable that embeds:
- TypeScript server code compiled to JavaScript
- Native node-pty module for PTY support
- Express.js for HTTP handling
- ws library for WebSocket support
- All dependencies bundled into single binary
server.ts
- HTTP server initialization and lifecycleapp.ts
- Express application setup and middlewarefwd.ts
- Main entry point for terminal forwardingpty/pty-manager.ts
- Native PTY process managementpty/session-manager.ts
- Terminal session lifecycleservices/terminal-manager.ts
- High-level terminal operationsservices/buffer-aggregator.ts
- Binary buffer optimizationroutes/sessions.ts
- REST API endpoints
- High-performance Bun runtime (3x faster than Node.js)
- Zero-copy buffer operations
- Native PTY handling with proper signal forwarding
- Asciinema recording for all sessions
- Binary buffer protocol for efficient streaming
- Graceful shutdown handling
Web Frontend
Technology Stack
Location:web/src/client/
directory
Core Technologies:
- TypeScript for type safety
- Lit Web Components for modern component architecture
- Tailwind CSS for styling
- xterm.js for terminal rendering
- Custom WebSocket client for binary buffer protocol
Component Architecture
Key Features
Dashboard:- Real-time session listing with 3-second polling
- One-click terminal creation
- Session metadata display (command, duration, status)
- Responsive grid layout
- Full ANSI color support via xterm.js
- Binary buffer protocol for efficient updates
- Copy/paste functionality
- Responsive terminal sizing
- URL highlighting and click support
- Mobile-friendly touch interactions
- Binary message format with 0xBF magic byte
- Delta compression for incremental updates
- Efficient buffer aggregation
- WebSocket reconnection logic
- Lazy loading of terminal sessions
iOS Application
Overview
Location:ios/VibeTunnel/
directory
Purpose: Native iOS companion app for mobile terminal access
Architecture
Key Components:VibeTunnelApp.swift
- Main app entry and lifecycleBufferWebSocketClient.swift
- WebSocket client with binary protocolTerminalView.swift
- Native terminal renderingTerminalHostingView.swift
- UIKit bridge for terminal displaySessionService.swift
- Session management API client
Features
- Native SwiftUI interface
- Server connection management
- Terminal rendering with gesture support
- Session listing and management
- Recording export functionality
- Advanced keyboard support
Binary Buffer Protocol Support
The iOS app implements the same binary buffer protocol as the web client:- Handles 0xBF magic byte messages
- Processes buffer snapshots and deltas
- Maintains terminal state synchronization
- Optimized for mobile bandwidth
Security Model
Authentication
Authentication Modes:- System user password authentication (default)
- Optional SSH key authentication (
--enable-ssh-keys
) - No authentication mode (
--no-auth
) - Local bypass authentication (
--allow-local-bypass
)
- Allows localhost connections to bypass authentication
- Optional token authentication via
--local-auth-token
- Implements anti-spoofing checks (IP, headers, hostname)
- See
web/SECURITY.md
for detailed security implications
- Main auth middleware:
web/src/server/middleware/auth.ts
- Local bypass logic:
web/src/server/middleware/auth.ts:24-87
- Security checks:
web/src/server/middleware/auth.ts:25-48
Network Security
Access Control:- Localhost-only mode by default (127.0.0.1)
- Network mode binds to 0.0.0.0
- CORS configuration for web access
- No built-in TLS (use reverse proxy or tunnels)
- Tailscale integration for VPN access
- Ngrok support for secure public URLs
- Both provide TLS encryption
- Authentication handled by tunnel providers
System Security
macOS App Privileges:- Hardened runtime with specific entitlements
- Allows unsigned executable memory (for Bun)
- Allows DYLD environment variables
- Code signed with Developer ID
- Notarized for Gatekeeper approval
- No persistent storage of terminal content
- Session recordings stored temporarily
- Passwords in Keychain with access control
- No telemetry or analytics
Session Management
Session Lifecycle
Session Model
TypeScript Definition (web/src/server/pty/types.ts
):
Session Operations
Creation:- Generate unique session ID (UUID)
- Spawn PTY process with command
- Initialize asciinema recording
- Register with SessionManager
- Return session details to client
- Process exit detection
- Automatic status updates
- Resource usage tracking
- Idle timeout handling (optional)
- SIGTERM to process group
- PTY cleanup
- Recording finalization
- WebSocket closure notification
- Memory cleanup
CLI Integration
vt Command
Installation: Thevt
command is installed as a wrapper script that automatically prepends ‘fwd’ to commands when using the Bun server.
Script Location: /usr/local/bin/vt
vibetunnel Binary
Location: Embedded in app bundle, copied to/usr/local/bin/vibetunnel
Commands:
vibetunnel serve
- Start server (used internally)vibetunnel fwd [command]
- Forward terminal sessionvibetunnel version
- Show version information
CLI Features
Command Parsing:- Automatic ‘fwd’ prepending for vt wrapper
- Shell detection and setup
- Working directory preservation
- Environment variable handling
- Special Claude shortcuts (
--claude
,--claude-yolo
)
- Parse command-line arguments
- Ensure server is running
- Create session via API
- Open browser to session URL
- Return session information
API Specifications
RESTful API
Base URL:http://localhost:4020
(default)
Authentication: Optional HTTP Basic Auth
Core Endpoints
GET /api/healthWebSocket Protocol
Endpoint:/api/sessions/:id/ws
Binary Buffer Protocol: Messages use custom format for efficiency
Binary Buffer Protocol
Overview
The binary buffer protocol optimizes terminal data transmission by sending full buffer snapshots and incremental updates.Message Format
Binary Message (TypedArray):- First byte: 0xBF (magic byte)
- Remaining bytes: Terminal buffer data or commands
- Input commands
- Resize events
- Control messages
Protocol Flow
-
Initial Connection:
- Client connects to WebSocket
- Server sends binary buffer snapshot
-
Incremental Updates:
- Server aggregates terminal output
- Sends deltas as text messages
- Periodically sends full binary snapshots
-
Client Input:
- Sent as JSON text messages
- Contains ‘input’ type and data
Implementation Details
Server (web/src/server/services/buffer-aggregator.ts
):
- Maintains terminal buffer state
- Aggregates small updates
- Sends snapshots every 5 seconds or on major changes
web/src/client/components/vibe-terminal-buffer.ts
):
- Handles binary buffer messages
- Applies incremental updates
- Manages terminal state
ios/VibeTunnel/Services/BufferWebSocketClient.swift
):
- Same protocol implementation
- Optimized for mobile performance
User Interface
Menu Bar Application
Components:- Status icon indicating server state
- Quick access menu
- Session count display
- Settings access
- About/Help options
- Gray: Server stopped
- Green: Server running
- Red: Error state
- Animated: Starting/stopping
Settings Window
General Tab:- Server port configuration
- Launch at login toggle
- Show in Dock option
- Update channel selection
- Access mode (localhost/network)
- Password protection toggle
- Authentication settings
- Dashboard URL display
- Cleanup on startup
- CLI tools installation
- Server console access
- Debug logging
- Server type display (Bun only)
- Console log viewer
- Diagnostic information
Configuration System
User Defaults
Storage:UserDefaults.standard
Key Settings:
Keychain Integration
DashboardKeychain Service:- Stores dashboard password securely
- Uses kSecClassInternetPassword
- Server and port-specific storage
- Handles password updates/deletion
Configuration Flow
- App Launch: Load settings from UserDefaults
- Server Start: Pass configuration via CLI arguments
- Runtime Changes: Update server without restart where possible
- Password Changes: Clear server auth cache
Build and Release
Build System
Requirements:- Xcode 16.0+
- macOS 14.0+ SDK
- Node.js 20.0+
- Bun runtime
- Build Bun executable from web sources
- Compile Swift application
- Copy resources (Bun binary, web assets)
- Code sign application
- Create DMG for distribution
Code Signing
Entitlements (mac/VibeTunnel/VibeTunnel.entitlements
):
Distribution
Release Process:- Build and sign application
- Create notarized DMG
- Generate Sparkle appcast
- Upload to GitHub releases
- Update appcast XML
- ARM64-only binary (Apple Silicon required)
- Embedded Bun server executable
- Web assets and resources
- Sparkle update framework
Testing Strategy
macOS Tests
Framework: Swift Testing (Swift 6) Test Organization:.critical
- Core functionality.networking
- Network operations.concurrency
- Async operations.security
- Security features
Node.js Tests
Framework: Vitest Test Structure:- 80% line coverage
- 80% function coverage
- 80% branch coverage
Performance Requirements
Latency Targets
Terminal I/O:- Keystroke to display: < 50ms
- Binary buffer update: < 100ms
- WebSocket ping/pong: < 10ms
- Session list: < 50ms
- Session creation: < 200ms
- Health check: < 10ms
Resource Usage
Memory:- macOS app idle: < 50MB
- Bun server idle: < 100MB
- Per session: < 10MB
- Buffer cache: 64KB per session
- Idle: < 1%
- Active session: < 5%
- Multiple sessions: Linear scaling
Scalability
Concurrent Sessions:- Target: 50 simultaneous sessions
- Tested: 100+ sessions
- Graceful degradation
- Buffer pooling for efficiency
Error Handling
Error Categories
User Errors:- Port already in use
- Invalid configuration
- Authentication failures
- Permission denied
- Server crash/restart
- PTY allocation failures
- Process spawn errors
- WebSocket disconnections
Error Recovery
Server Crashes:- Automatic restart by ServerManager
- Session state preserved in memory
- Client reconnection supported
- Graceful degradation
- WebSocket auto-reconnect
- Exponential backoff
- Session state preserved
- Buffer replay on reconnect
Update System
Sparkle Integration
Configuration:- Update check interval: 24 hours
- Automatic download in background
- User prompt for installation
- Delta updates supported
- Stable: Production releases
- Pre-release: Beta testing
Update Process
- Check appcast.xml for updates
- Download update package
- Verify EdDSA signature
- Prompt user for installation
- Install and restart application
Platform Integration
macOS Integration
System Features:- Launch at login via SMAppService
- Menu bar and Dock modes
- Notification Center support
- Keyboard shortcuts
- AppleScript support
Terminal Integration
Supported Terminals:- Terminal.app (default)
- iTerm2
- Warp
- Alacritty
- Hyper
- kitty
- Check bundle identifiers
- Verify app existence
- User preference storage