- Enhanced /buffers WebSocket endpoint to aggregate updates from all remotes
- Added remote WebSocket connection management with proper Bearer auth
- Implemented connection pooling and automatic reconnection
- Forward binary buffer messages transparently from remotes to clients
- Track subscriptions per remote and handle cleanup properly
- Support both local and remote sessions through unified interface
This enables real-time terminal viewing across distributed VibeTunnel instances.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Complete architectural overview of VibeTunnel server
- Detailed protocol specifications for all components
- Binary buffer encoding format documentation
- HQ mode distributed architecture details
- API endpoint reference with examples
- WebSocket protocol specifications
- File system structure and session storage format
- Implementation notes for cross-language compatibility
This specification enables implementing VibeTunnel servers in any language
while maintaining full compatibility with the protocol and architecture.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Remove registration retry from HQClient, let caller handle retries
- Make HQClient destroy method async and await unregister
- Remove session ID namespacing - UUIDs are unique enough
- Add /api/health endpoint for cheaper health checks
- Remove unnecessary RemoteServer.status field
- Track sessions by remote using sessionIds Set
- Fix remote session creation to use remote's token (not HQ's auth)
- Update session proxy to lookup remote by session ID
- Make cleanup-exited work across all remotes
- Remove tty_fwd_path code - always use node-pty
- Fix duplicate HQ endpoints
- Improve health check to try /api/health first, fall back to /api/sessions
- Remove offline remotes automatically on failed health check
BREAKING CHANGES:
- HQClient.destroy() is now async
- RemoteServer no longer has status field
- Session IDs are no longer namespaced with remoteId prefix
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
**Platform-Optimized Strategy:**
- **POSIX Systems** (Linux, macOS, FreeBSD): Use efficient kill(pid, 0)
- **Windows Only**: Use gopsutil.PidExists() when kill() unavailable
**Implementation:**
- Primary: kill(pid, 0) on all POSIX platforms (most efficient)
- Fallback: gopsutil only on Windows (where kill() doesn't exist)
- No unnecessary overhead - each platform uses optimal method
**Benefits:**
- Maximum Performance: POSIX systems use native kill(pid, 0)
- Windows Support: gopsutil provides Windows compatibility
- Minimal Dependencies: gopsutil only loaded when needed
- Platform Optimal: Each OS uses its most efficient method
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: Claude <noreply@anthropic.com>
- Add mandatory --name parameter when using --hq-url
- Ensure remote server names are unique across the HQ
- Return 409 Conflict when duplicate name is registered
- Track remotes by both ID and name in RemoteRegistry
- Add /api/remotes endpoints for HQ mode
- Improve error messages for registration failures
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: optimize Go server CPU usage from 500%+ to efficient levels
Major performance improvements to resolve excessive CPU consumption:
**Critical Fixes:**
- Remove WebSocket busy loop that caused continuous CPU spinning
- Fix microsecond-level polling (100μs → 10ms) reducing 100x operations
- Replace ps subprocess calls with efficient kill(pid,0) syscalls
- Increase timer intervals (1s → 30s) for session status checks
**Optimizations:**
- Control FIFO polling: 100ms → 1s intervals
- Select timeout: 100ms → 1s to reduce unnecessary wakeups
- Smart status caching: skip checks for already-exited sessions
- Remove unused imports (os/exec, strconv)
**Impact:**
- Eliminates tight loops causing 10,000+ operations per second
- Reduces subprocess overhead from frequent ps command executions
- Changes from polling-based to efficient event-driven architecture
- Expected CPU usage reduction from 500%+ to levels comparable with Node.js version
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: prevent WebSocket channel close panic with sync.Once
- Add sync.Once to prevent double-closing of done channel
- Update handleTextMessage signature to accept close function
- Use closeOnceFunc for safe channel closure across goroutines
Fixes panic: 'close of closed channel' in WebSocket handler
* feat: add --do-not-allow-column-set flag to disable resizing for spawned sessions
**New Flag:**
- `--do-not-allow-column-set` (default: true) - Disables terminal resizing for spawned shells
- Only affects sessions created with `spawn_terminal=true`
- Detached sessions (command-line, API without spawn) always allow resizing
**Implementation:**
- Add `IsSpawned` field to session.Config and session.Info structs
- Track whether session was spawned in terminal vs detached
- Server checks flag + spawn status before allowing resize operations
- Returns descriptive error for blocked resize attempts
**Behavior:**
- Spawned sessions: Resize blocked when flag enabled (default)
- Detached sessions: Always allow resizing regardless of flag
- Existing sessions preserve their resize capabilities
**API Response for blocked resize:**
```json
{
"success": false,
"message": "Resizing is disabled for spawned sessions",
"error": "resize_disabled_for_spawned_sessions"
}
```
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* feat: extend --do-not-allow-column-set flag to block ALL session resizing
**Breaking Change:** Flag now affects both spawned AND detached sessions
**Changes:**
- Remove `sess.IsSpawned()` check in resize handler
- Block resizing for ALL sessions when flag is enabled (default: true)
- Update flag description: "Disable terminal resizing for all sessions (spawned and detached)"
- Update error message: "Terminal resizing is disabled by server configuration"
- Update error code: "resize_disabled_by_server"
**New Behavior:**
- `--do-not-allow-column-set=true` (default): NO resizing for any session type
- `--do-not-allow-column-set=false`: Allow resizing for all session types
- Applies uniformly to both spawned terminal windows and detached CLI sessions
**API Response for blocked resize:**
```json
{
"success": false,
"message": "Terminal resizing is disabled by server configuration",
"error": "resize_disabled_by_server"
}
```
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
- Add VIBETUNNEL_USERNAME/PASSWORD env vars and --username/--password CLI args
- Separate local auth from HQ registration auth (--hq-username/--hq-password)
- Validate that both username and password are provided or neither
- Update authentication to use configured username instead of hardcoded 'admin'
- Fix type errors and lint issues
BREAKING CHANGE: Authentication now requires both username and password to be specified together
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Remote servers now accept both Basic Auth (for clients) and Bearer token (for HQ)
- Basic Auth now requires username 'admin' (not any username)
- Remote sends its token to HQ during registration for HQ to use
- HQ uses Bearer token when calling remote APIs (not Basic Auth)
- Remote uses HQ's Basic Auth when registering/unregistering with HQ
- WebSocket connections also support both auth methods
- Display token in console when running as remote for debugging
This creates proper separation:
- Clients authenticate with servers using Basic Auth
- Remotes authenticate with HQ using HQ's Basic Auth
- HQ authenticates with remotes using remote's Bearer token
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Remove heartbeat mechanism from HQClient - now just registers and forgets
- Update RemoteRegistry to actively check remote health via GET /api/sessions
- Remove /api/remotes/:remoteId/heartbeat endpoint as it's no longer needed
- Pass password to RemoteRegistry for authenticated health checks
- Remote servers no longer need to maintain connection to HQ after registration
- HQ checks remote health every 15 seconds with 5 second timeout
This simplifies the architecture - remotes just tell HQ they exist, and HQ
is responsible for monitoring their health status.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Modify GET /api/sessions to aggregate sessions from all online remotes
- Add remoteId and remoteName fields to session responses
- Implement session ID namespacing (remoteId:sessionId) to prevent collisions
- Add remoteId parameter to POST /api/sessions for creating remote sessions
- Create proxy middleware for forwarding session operations to remote servers
- Apply proxy middleware to all session-specific endpoints
- Handle offline remotes gracefully with proper error responses
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add --hq flag to enable HQ mode for centralized management
- Add --join-hq flag for remote servers to register with HQ
- Implement RemoteRegistry for managing remote server connections
- Add HQClient for remote servers to register and send heartbeats
- Add /api/remotes endpoints for registration, heartbeat, and listing
- Enforce HTTPS requirement for HQ URLs for security
- Add graceful shutdown handling for HQ components
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Added HackNerdFontMono-Bold.ttf to improve terminal font rendering
with better bold character support and enhanced readability.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: Claude <noreply@anthropic.com>
* feat: add terminal max width option
- Add terminal preferences manager for persistent settings storage
- Add maxCols property to terminal component with width constraint logic
- Add UI toggle button (∞/80) in session header for easy width control
- Default behavior unchanged: unlimited width (takes full container)
- Optional 80-column max width limit when enabled
- Preferences saved to localStorage and restored on page load
- Real-time updates without page refresh
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* feat: enhance terminal width selector with common presets and custom input
- Add common terminal width presets: ∞, 80, 100, 120, 132, 160
- Add custom width input field (20-500 columns)
- Replace simple toggle with dropdown selector UI
- Include helpful descriptions for each preset
- Support keyboard shortcuts (Enter to submit, Escape to cancel)
- Add click-outside-to-close functionality
- Maintain all existing preferences persistence
- Show current width in button label and tooltip
Common widths:
- 80: Classic terminal
- 100: Modern standard
- 120: Wide terminal
- 132: Mainframe width
- 160: Ultra-wide
- Custom: User-defined (20-500)
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* fix: prevent WebSocket send on closed channel panic
Added safeSend helper function with panic recovery to handle race conditions
when multiple goroutines access WebSocket channels. Replaces unsafe channel
sends with graceful error handling.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
- Update color scheme to use dark backgrounds (#0a0a0a, #1a1a1a, #242424)
- Add vibrant green accent colors (#00ff88) with glow effects
- Update Tailwind configuration with new theme colors and utilities
- Add reusable CSS component classes (btn-primary, btn-secondary, btn-ghost, card, input-field)
- Replace inline styles across all components with theme classes
- Create new terminal icon component with glow effect
- Update app header with redesigned layout and session stats
- Update session cards with improved visual hierarchy
- Redesign session create form and file browser modals
- Update session view with consistent theme styling
- Apply theme to mobile controls and overlays
- Update all status indicators to use theme colors
- Add smooth transitions and hover effects throughout
- Fix working directory validation to fall back to home directory when iOS sends invalid paths
- Fix file browser API client to handle correct response format (absolutePath + files)
- Improve session creation header design with translucent material and fixed height
- Add authentication support placeholder for future API protection
- Add better error logging for debugging API issues
- Move TerminalTextFieldStyle to SessionCreateView for better organization
The iOS app can now create sessions successfully and browse directories without errors.
- Add 'claude' as the first quick start command
- Set 'claude' as the default command instead of 'zsh'
- Add sparkle icon for Claude command
- Remove 'irb' to make room for Claude in the grid
- Change from bright accent fill to dark terminal background
- Add accent color border that gets thicker when active
- Use accent color for text instead of terminal foreground
- Better visual consistency with the dark terminal aesthetic
Major improvements to the iOS VibeTunnel app:
SwiftTerm Integration:
- Properly integrated SwiftTerm 1.2.5 for terminal emulation
- Fixed naming conflicts and API compatibility issues
- Added proper actor isolation with @preconcurrency
- Terminal data now feeds correctly via SSE streams
Session Management:
- Fixed session model to match Go server's JSON response format
- Added CodingKeys mapping for field name differences (cmdline, cwd, etc.)
- Support for "starting" session status
- Enhanced date parsing for both ISO8601 and RFC3339 formats
Working Directory Fixes:
- Changed default working directory from iOS sandbox to server paths
- Now uses ~/ as default (matching web frontend)
- Added common server directories as quick options
- Server expands ~ to actual home directory
Terminal Streaming:
- Implemented Asciinema cast v2 format parsing
- SSE client properly handles output, resize, and exit events
- Added terminal snapshot loading for existing sessions
- Fixed special key handling with proper ANSI escape sequences
UI Improvements:
- Updated session list to grid layout (2 columns)
- Added session count and "Kill All" functionality
- Redesigned session cards with inline kill/clean buttons
- Shows command and working directory in session preview
Error Handling:
- Added comprehensive logging for debugging
- Enhanced error messages for better user experience
- Detailed API request/response logging
- Network error descriptions (connection refused, timeout, etc.)
Server Configuration:
- Set default server address to 127.0.0.1:4020
- Sessions now created with spawn_terminal: false for PTY mode
- Both web and iOS clients can share terminal sessions
The iOS app now provides a full terminal experience using SwiftTerm,
mirroring the web frontend's functionality with proper server integration.
- Add xcodegen project specification (project.yml)
- Configure for iOS 18.0+ deployment target
- Add SwiftTerm package dependency
- Create asset catalogs:
- App icon placeholder
- Accent color (terminal blue)
- Terminal background color
- Configure proper Info.plist settings
- Set up build configurations and schemes
The project is now ready to open in Xcode.
- Beautiful terminal-inspired UI design with custom theme
- Full SwiftUI implementation targeting iOS 18+
- SwiftTerm integration for terminal emulation
- Real-time session management with SSE streaming
- Complete feature parity with web frontend:
- Server connection management
- Session list with auto-refresh
- Create, kill, and cleanup sessions
- Full terminal emulation with input/output
- Keyboard toolbar with special keys
- Font size adjustment
- Haptic feedback throughout
- Comprehensive error handling and loading states
- iPad optimizations (basic, split view pending)
- Complete documentation and setup instructions
The app provides a native, performant alternative to the web interface
with a stunning dark theme and smooth animations.