vibetunnel/web/spec.md
2025-06-27 21:13:55 +02:00

16 KiB

VibeTunnel Codebase Map

A comprehensive navigation guide for the VibeTunnel web terminal system.

Project Overview

VibeTunnel is a web-based terminal multiplexer with distributed architecture support. It provides:

  • PTY-based terminal sessions via node-pty
  • Real-time terminal streaming via SSE (asciinema cast files)
  • Binary-optimized buffer synchronization (current viewport via WebSocket)
  • Distributed HQ/remote server architecture
  • Web UI with full terminal emulation
  • Push notifications for terminal bell events
  • Multi-method authentication (SSH keys, JWT, PAM)

Directory Structure

web/
├── src/
│   ├── server/           # Node.js Express server
│   │   ├── middleware/   # Auth and other middleware
│   │   ├── pty/         # PTY management
│   │   ├── routes/      # API endpoints
│   │   ├── services/    # Core services
│   │   ├── server.ts    # Main server implementation
│   │   └── fwd.ts       # CLI forwarding tool
│   ├── client/           # Lit-based web UI
│   │   ├── assets/      # Static files (fonts, icons, html)
│   │   ├── components/  # UI components
│   │   ├── services/    # Client services
│   │   └── utils/       # Client utilities
│   ├── test/            # Test files
│   └── cli.ts           # Main entry point
├── scripts/             # Build scripts
└── public/              # Built static assets (generated)

Server Architecture (src/server/)

Core Components

Entry Points

  • cli.ts (1-62): Main entry point, routes to server or forward mode
  • server/server.ts (1-953): Core server implementation with Express app factory
    • CLI parsing (132-236): Extensive configuration options
    • Server modes (432-444): Normal, HQ, Remote initialization
    • WebSocket upgrade (564-677): Authentication and buffer streaming
    • Graceful shutdown (888-944): Cleanup intervals and service termination

Authentication (middleware/auth.ts)

  • Multi-method authentication (1-159)
    • SSH key authentication with Ed25519 support
    • Basic auth (username/password)
    • Bearer token for HQ↔Remote communication
    • JWT tokens for session persistence
  • Local bypass for localhost connections (24-48, 68-87)
  • Query parameter token support for EventSource

Session Management

PTY Manager (pty/pty-manager.ts)

  • Session creation (78-163): Spawns PTY processes with node-pty
  • Automatic alias resolution (191-204): Uses ProcessUtils.resolveCommand()
  • Terminal resize handling (63-157): Dimension synchronization
  • Control pipe support using file watching on all platforms
  • Bell event emission for push notifications
  • Clean termination with SIGTERM→SIGKILL escalation

Process Utils (pty/process-utils.ts)

  • resolveCommand() (242-378): Detects if command exists in PATH
    • Uses which (Unix) or where (Windows) to check existence
    • Returns appropriate shell command for aliases/builtins
    • Sources shell config files for proper alias support
  • getUserShell() (384-484): Determines user's preferred shell
    • Checks $SHELL environment variable first
    • Platform-specific fallbacks (pwsh/cmd on Windows, zsh/bash on Unix)
  • Interactive shell detection (220-235): Auto-adds -i -l flags

Session Manager (pty/session-manager.ts)

  • Session persistence in ~/.vibetunnel/control/
  • Filesystem-based session discovery
  • Zombie session cleanup

Terminal Manager (services/terminal-manager.ts)

  • Headless xterm.js for server-side state
  • Binary buffer snapshot generation
  • Watches asciinema cast files and applies to terminal
  • Debounced buffer change notifications

API Routes (routes/)

Sessions (sessions.ts)

  • GET /api/sessions (51-124): List all sessions
    • Returns array with source: 'local' | 'remote'
    • HQ mode: Aggregates from all remote servers
  • POST /api/sessions (126-265): Create session
    • Body: { command, workingDir?, name?, remoteId?, spawn_terminal? }
    • Returns: { sessionId: string, message?: string }
  • GET /api/sessions/:id (369-410): Get session info
  • DELETE /api/sessions/:id (413-467): Kill session
  • DELETE /api/sessions/:id/cleanup (470-518): Clean session files
  • POST /api/cleanup-exited (521-598): Clean all exited sessions

Session I/O

  • POST /api/sessions/:id/input (874-950): Send keyboard input
    • Body: { text: string } OR { key: SpecialKey }
  • POST /api/sessions/:id/resize (953-1025): Resize terminal
    • Body: { cols: number, rows: number }
  • POST /api/sessions/:id/reset-size (1028-1083): Reset to native size

Session Output

  • GET /api/sessions/:id/stream (723-871): SSE streaming
    • Streams asciinema v2 format with custom exit event
    • Replays existing content, then real-time streaming
  • GET /api/sessions/:id/buffer (662-721): Binary buffer snapshot
  • GET /api/sessions/:id/text (601-659): Plain text output
    • Optional ?styles for markup: [style fg="15" bold]text[/style]

Activity Monitoring

  • GET /api/sessions/activity (268-324): All sessions activity
  • GET /api/sessions/:id/activity (327-366): Single session activity
    • Returns: { isActive: boolean, timestamp: string, session: SessionInfo }

Remotes (remotes.ts) - HQ Mode Only

  • GET /api/remotes (19-33): List registered servers
  • POST /api/remotes/register (36-64): Register remote
  • DELETE /api/remotes/:id (67-84): Unregister remote
  • POST /api/remotes/:id/refresh-sessions (87-152): Refresh session list

Logs (logs.ts)

  • POST /api/logs/client (21-53): Client log submission
  • GET /api/logs/raw (56-74): Stream raw log file
  • GET /api/logs/info (77-102): Log file metadata
  • DELETE /api/logs/clear (105-119): Clear log file

Binary Buffer Protocol

Note: "Buffer" refers to the current terminal viewport without scrollback - used for terminal previews.

Format (terminal-manager.ts:361-555)

Header (32 bytes):
- Magic: 0x5654 "VT" (2 bytes)
- Version: 0x01 (1 byte)
- Flags: reserved (1 byte)
- Dimensions: cols, rows (8 bytes)
- Cursor: X, Y, viewport (12 bytes)
- Reserved (4 bytes)

Rows: 0xFE=empty, 0xFD=content
Cells: Variable-length with type byte

SSE Streaming and Asciinema Files

Asciinema Writer (pty/asciinema-writer.ts)

  • Writes cast files to ~/.vibetunnel/control/[sessionId]/stream-out
  • Format:
    • Standard: [timestamp, "o", output] for terminal output
    • Standard: [timestamp, "i", input] for user input
    • Standard: [timestamp, "r", "colsxrows"] for resize events
    • Custom: ["exit", exitCode, sessionId] when process terminates

SSE Streaming (routes/sessions.ts:723-871)

  • Real-time streaming of asciinema cast files
  • Replays existing content with zeroed timestamps
  • Watches for new content and streams incrementally
  • Heartbeat every 30 seconds

WebSocket (services/buffer-aggregator.ts)

  • Client connections (30-87): Authentication and subscription
  • Message handling (88-127): Subscribe/unsubscribe/ping
  • Binary protocol (156-209): [0xBF][ID Length][Session ID][Buffer Data]
  • Local and remote session proxy support

Activity Monitoring (services/activity-monitor.ts)

  • Monitors stream-out file size changes (143-146)
  • 100ms check interval (41-44)
  • 500ms inactivity timeout (209-212)
  • Persists to activity.json per session (220-245)
  • Works for all sessions regardless of creation method

HQ Mode Components

Remote Registry (services/remote-registry.ts)

  • Health checks every 15s (150-187)
  • Session ownership tracking (91-148)
  • Bearer token authentication
  • Automatic unhealthy remote removal

HQ Client (services/hq-client.ts)

  • Registration with HQ (40-90)
  • Unique ID generation with UUID v4
  • Graceful unregistration on shutdown (92-113)

Additional Services

Push Notifications (services/push-notification-service.ts)

  • Web Push API integration (64-363)
  • Subscription management in ~/.vibetunnel/notifications/
  • Bell event notifications (231-247)
  • Automatic expired subscription cleanup

Bell Event Handler (services/bell-event-handler.ts)

  • Processes terminal bell events (59-182)
  • Integrates with push notifications
  • Includes process context in notifications

Authentication Service (services/auth-service.ts)

  • SSH key authentication (144-159, 201-271)
    • Ed25519 signature verification
    • Challenge-response system
    • Checks ~/.ssh/authorized_keys
  • Password authentication (105-120)
  • PAM authentication fallback (184-196)
  • JWT token management (176-180)

Control Directory Watcher (services/control-dir-watcher.ts)

  • Monitors external session changes (20-175)
  • HQ mode integration (116-163)
  • Detects new/removed sessions

Utilities

Logger (utils/logger.ts)

  • Structured logging with file and console output (1-186)
  • Color-coded console with chalk
  • Log levels: log, warn, error, debug
  • File output to ~/.vibetunnel/log.txt
  • Debug mode via VIBETUNNEL_DEBUG

VAPID Manager (utils/vapid-manager.ts)

  • Auto-generates VAPID keys for push notifications (20-331)
  • Stores in ~/.vibetunnel/vapid/keys.json
  • Key rotation support

Client Architecture (src/client/)

Core Components

Entry Points

  • app-entry.ts (1-28): Main entry, initializes Monaco and push notifications
  • test-entry.ts: Test terminals entry
  • styles.css: Global Tailwind styles

Main Application (app.ts)

  • Lit-based SPA (15-1200+): <vibetunnel-app>
  • URL-based routing with ?session=<id>
  • Global keyboard handlers (Cmd+O, Escape)
  • View management: auth/list/session
  • Events fired:
    • toggle-nav, navigate-to-list, error, success, navigate

Component Event Architecture

vibetunnel-app
├── app-header (navigation, controls)
├── session-list (when view='list')
│   └── session-card (per session)
│       └── vibe-terminal-buffer (terminal preview)
├── session-view (when view='session')
│   ├── session-header
│   ├── vibe-terminal (main terminal)
│   ├── mobile-input-overlay
│   ├── ctrl-alpha-overlay
│   └── terminal-quick-keys
├── session-create-form (modal)
├── file-browser (modal)
├── unified-settings (modal)
└── auth-login (when view='auth')

Terminal Components

Terminal (terminal.ts)

  • Full xterm.js implementation (1-1000+)
  • Virtual scrolling (537-555)
  • Touch/momentum support
  • URL highlighting integration
  • Events: terminal-ready, terminal-input, terminal-resize, url-clicked

VibeTunnelBuffer (vibe-terminal-buffer.ts)

  • Read-only terminal preview (25-268)
  • WebSocket buffer subscription
  • Auto-resizing
  • Events: content-changed

SessionView (session-view.ts)

  • Full-screen terminal view (29-1331)
  • Manager architecture:
    • ConnectionManager: SSE streaming
    • InputManager: Keyboard/mouse
    • MobileInputManager: Mobile input
    • DirectKeyboardManager: Direct keyboard access
    • TerminalLifecycleManager: Terminal state
  • Events: navigate-to-list, error, warning

Session Management Components

SessionList (session-list.ts)

  • Grid/list layout (61-700+)
  • Hide/show exited sessions
  • Search and filtering
  • Events: navigate-to-session, refresh, error, success

SessionCard (session-card.ts)

  • Individual session display (31-420+)
  • Live terminal preview
  • Activity detection
  • Events: session-select, session-killed, session-kill-error

SessionCreateForm (session-create-form.ts)

  • Modal dialog (27-381)
  • Command input with working directory
  • Native terminal spawn option
  • Events: session-created, cancel, error

UI Components

AppHeader (app-header.ts)

  • Main navigation (15-280+)
  • Session status display
  • Theme toggle
  • Events: toggle-nav, navigate-to-list, toggle-create-form

FileBrowser (file-browser.ts)

  • Filesystem navigation (48-665)
  • Git status display
  • Monaco editor preview
  • Events: insert-path, open-in-editor, directory-selected

LogViewer (log-viewer.ts)

  • Real-time log display (1-432)
  • SSE-style polling
  • Level filtering
  • Search functionality

Services

BufferSubscriptionService (buffer-subscription-service.ts)

  • WebSocket client (30-87)
  • Binary protocol decoder (163-208)
  • Auto-reconnection with backoff
  • Per-session subscriptions

PushNotificationService (push-notification-service.ts)

  • Service worker registration
  • Push subscription management
  • Notification action handling

AuthClient (auth-client.ts)

  • Token management
  • Authentication state
  • API header generation

Utils

CastConverter (cast-converter.ts)

  • Asciinema v2 parser (31-82)
  • SSE stream handler (294-427)
  • Custom exit event support

TerminalRenderer (terminal-renderer.ts)

  • Binary buffer decoder (279-424)
  • HTML generation from buffer
  • Style mapping

URLHighlighter (url-highlighter.ts)

  • Multi-line URL detection
  • Protocol validation
  • Click event handling

Forward Tool (src/server/fwd.ts)

Purpose

CLI tool for spawning PTY sessions using VibeTunnel infrastructure.

Usage

npx tsx src/fwd.ts [--session-id <id>] <command> [args...]

# Examples
npx tsx src/fwd.ts claude --resume
npx tsx src/fwd.ts --session-id abc123 bash -l

Key Features

  • Interactive terminal forwarding (43-195)
  • Automatic shell alias support via ProcessUtils
  • Session ID pre-generation support
  • Graceful cleanup on exit
  • Colorful output with chalk

Integration Points

  • Uses central PTY Manager (78-82)
  • Control pipe handling delegated to PTY Manager
  • Terminal resize synchronization (148-163)
  • Raw mode for proper input capture (166-172)

Build System

Main Build (scripts/build.js)

  • Asset copying (7-121)
  • CSS compilation with Tailwind
  • Client bundling with esbuild
  • Server TypeScript compilation
  • Native executable creation

Native Binary (scripts/build-native.js)

  • Node.js SEA integration (1-537)
  • node-pty patching for compatibility (82-218)
  • Outputs:
    • native/vibetunnel: Main executable
    • native/pty.node: Terminal emulation
    • native/spawn-helper: Process spawning (macOS)
    • native/authenticate_pam.node: PAM auth

Key Files Quick Reference

Server Core

  • src/cli.ts: Main entry point
  • src/server/server.ts: Server implementation
  • src/server/middleware/auth.ts: Authentication
  • src/server/routes/sessions.ts: Session API
  • src/server/pty/pty-manager.ts: PTY management
  • src/server/services/terminal-manager.ts: Terminal state
  • src/server/services/activity-monitor.ts: Activity tracking
  • src/server/fwd.ts: CLI forwarding tool

Client Core

  • src/client/app-entry.ts: Entry point
  • src/client/app.ts: Main SPA
  • src/client/components/terminal.ts: Terminal renderer
  • src/client/components/session-view.ts: Session viewer
  • src/client/services/buffer-subscription-service.ts: WebSocket
  • src/client/utils/cast-converter.ts: Asciinema parser

Configuration

  • Environment: PORT, VIBETUNNEL_USERNAME, VIBETUNNEL_PASSWORD, VIBETUNNEL_DEBUG
  • CLI: --port, --username, --password, --hq, --hq-url, --name
  • Debug logging: Set VIBETUNNEL_DEBUG=1 or true

Protocols

  • REST API: Session CRUD, terminal I/O
  • SSE: Real-time asciinema streaming
  • WebSocket: Binary buffer updates
  • Control pipes: External session control

Session Data Storage

Each session has a directory in ~/.vibetunnel/control/[sessionId]/:

  • session.json: Session metadata
  • stream-out: Asciinema cast file
  • stdin: Input pipe
  • control: Control pipe
  • activity.json: Activity status

Development Notes

Recent Improvements

  • Push notification support for terminal bells
  • Multi-method authentication (SSH keys, JWT, PAM)
  • Unified logging infrastructure with style guide
  • Activity monitoring for all sessions
  • Control directory watcher for external sessions
  • Improved TypeScript types (no "as any")
  • Colorful CLI output with chalk
  • Auto-generation of security keys (VAPID)

Testing

  • Unit tests: pnpm test
  • E2E tests: pnpm run test:e2e
  • Vitest configuration with coverage

Key Dependencies

  • node-pty: Cross-platform PTY
  • @xterm/headless: Terminal emulation
  • Lit: Web components
  • Express: HTTP server
  • web-push: Push notifications
  • TailwindCSS: Styling