* 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>
- Switch from JSON to binary format for buffer data transfer
- Optimize encoding with run-length encoding for empty rows
- Reduce data size with efficient cell encoding (1 byte for spaces, variable for complex cells)
- Support both palette and RGB colors with minimal overhead
- Pre-calculate exact buffer sizes to avoid allocations
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Reduce data transfer by omitting trailing blank cells
- Keep at least one cell per line to maintain structure
- Handle empty lines efficiently with single space cell
- Add fallback rendering for completely empty lines
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add fitHorizontally mode to vibe-terminal-buffer component
- Scale font size to fit entire terminal width when enabled
- Trim blank lines from bottom of buffer to reduce data transfer
- Always show content from top down (not centered on cursor)
- Match behavior of terminal.ts fitTerminal implementation
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
The binary encoding was using 16-bit unsigned integers which failed when:
- Terminal has many rows (>65k)
- Cursor is above the viewport (negative relative position)
Changes:
- Upgrade to version 2 of the binary format
- Use 32-bit integers for dimensions and positions
- Use signed integers for viewport/cursor positions
- Update header size from 16 to 32 bytes
- Update documentation to reflect new format
This fixes the issue where cursorY could be negative when the cursor
is above the visible viewport (e.g., cursorY=0, viewportY=46 results
in relative cursorY=-46).
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Replace terminal.ts in session-card with new buffer-based component that:
- Fetches terminal buffer snapshots via JSON API
- Polls every second only when content changes (checks lastModified)
- Automatically calculates lines needed based on container height
- Reuses terminal rendering styles and logic
Changes:
- Create terminal-renderer.ts with shared rendering logic for both components
- Add vibe-terminal-buffer component that works with buffer API
- Update session-card to use vibe-terminal-buffer instead of vibe-terminal
- Add terminal-line CSS for proper styling
- Fix color handling in terminal-manager (-1 means default color)
- Add debug logging to help diagnose rendering issues
The new approach is more efficient - no cast file parsing, just direct
buffer snapshots from the server.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Removed lint_output.txt from git tracking
- Added lint_output.txt to .gitignore to prevent future commits
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Add Linux implementation of VibeTunnel
This commit introduces a complete Linux port of VibeTunnel, providing feature parity with the macOS version. The implementation includes:
- Full Go-based server with identical REST API and WebSocket endpoints
- Terminal session management using PTY (pseudo-terminal) handling
- Asciinema recording format for session playback
- Compatible CLI interface matching the macOS `vt` command
- Support for all VibeTunnel features: password protection, network modes, ngrok integration
- Comprehensive build system with Makefile supporting various installation methods
- Systemd service integration for running as a system daemon
The Linux version maintains 100% compatibility with the existing web UI and can be used as a drop-in replacement for the macOS app on Linux systems.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Add comprehensive ngrok integration to Linux VibeTunnel
Implements full ngrok tunnel support for the Go/Linux version to match
the macOS Swift implementation, enabling secure public access to local
VibeTunnel instances.
- **ngrok Service**: Complete lifecycle management with status tracking
- **HTTP API**: RESTful endpoints matching macOS version
- **CLI Support**: Command-line ngrok flags and integration
- **Auto-forwarding**: Built-in HTTP request forwarding to local server
- `POST /api/ngrok/start` - Start tunnel with auth token
- `POST /api/ngrok/stop` - Stop active tunnel
- `GET /api/ngrok/status` - Get current tunnel status
- Uses `golang.ngrok.com/ngrok` SDK for native Go integration
- Thread-safe service with mutex protection
- Comprehensive error handling and logging
- Real-time status updates (disconnected/connecting/connected/error)
- Proper context cancellation for graceful shutdown
```bash
vibetunnel --serve --ngrok --ngrok-token "your_token"
vibetunnel --serve --port 4030 --ngrok --ngrok-token "your_token"
```
- Added golang.ngrok.com/ngrok v1.13.0
- Updated web packages (security fixes for puppeteer)
Maintains full API compatibility with macOS VibeTunnel for seamless
cross-platform operation and consistent web frontend integration.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* up
* Fix SSE streaming performance with byte-based approach
Addresses @badlogic's review feedback to prevent performance issues
with line-based file reading in processNewContent().
## Changes Made
### Performance Fix
- **Byte-based seeking**: Replace line counting with file position tracking
- **Efficient reads**: Only read new content since last position using file.Seek()
- **Memory optimization**: Avoid reading entire file on each update
- **Incomplete line handling**: Properly handle partial lines at file end
### Technical Details
- Changed lastLineCount *int → seenBytes *int64
- Use file.Seek(seenBytes, 0) to jump to last read position
- Read only new content with currentSize - seenBytes
- Handle incomplete lines by adjusting seek position
- Maintains same functionality with better performance
### Benefits
- **Scalability**: No longer reads entire file for each update
- **Performance**: O(new_content) instead of O(total_content)
- **Memory**: Constant memory usage regardless of file size
- **Reliability**: Handles concurrent writes and partial lines correctly
This prevents the SSE streaming from exploding in our faces as @badlogic
warned, especially for long-running sessions with large output files.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Optimize streaming performance to reduce 1+ second delays
Implements multiple optimizations to address user-reported 1+ second delay
between typing and stream rendering:
## PTY Reading Optimizations
- **Reduced sleep times**: 100ms → 1ms for EOF checks
- **Faster polling**: 10ms → 1ms for zero-byte reads
- **FIFO optimization**: 1s → 100ms for stdin EOF polling
## UTF-8 Buffering Improvements
- **Timeout-based flushing**: 5ms timer for incomplete UTF-8 sequences
- **Real-time streaming**: Don't wait for complete sequences in interactive mode
- **Smart buffering**: Balance correctness with responsiveness
## File I/O Optimizations
- **Immediate sync**: Call file.Sync() after each write for instant fsnotify
- **Reduced SSE timeout**: 1s → 100ms for session alive checks
- **Better responsiveness**: Ensure file changes trigger immediately
## Technical Changes
- Added StreamWriter.scheduleFlush() with 5ms timeout
- Enhanced writeEvent() with conditional file syncing
- Optimized PTY read/write loop timing
- Improved SSE streaming frequency
These changes target the main bottlenecks identified in the
PTY → file → fsnotify → SSE → browser pipeline.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix critical stdin polling delay causing 1+ second input lag
- Reduced FIFO EOF polling from 100ms to 1ms
- Reduced EAGAIN polling from 1ms to 100µs
- Added immediate continue after successful writes
- This eliminates the major input delay bottleneck
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix critical performance issues causing resource leaks and CPU burns
Performance optimizations based on code review feedback:
1. **Fix SSE goroutine leaks**:
- Added client disconnect detection to SSE streams
- Propagate write errors to detect when clients close connections
- Prevents memory leaks from abandoned streaming goroutines
2. **Fix PTY busy-loop CPU burn**:
- Increased sleep from 1ms to 10ms in idle scenarios
- Reduces CPU wake-ups from 1000/s to 100/s (10x improvement)
- Significantly reduces CPU usage when PTY is idle
3. **Multi-stream disconnect detection**:
- Added error checking to multi-stream write operations
- Prevents goroutine leaks in multi-session streaming
These fixes address the "thing of the things" - performance\!
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Standardize session creation API response format to match Rust server
Changes:
- Updated Go server session creation response to include success/message/error fields
- Now returns: {"success": true, "message": "Session created successfully", "error": null, "sessionId": "..."}
- Maintains backward compatibility with existing sessionId field
- Go server already supported both input formats (cmdline/command, cwd/workingDir)
This achieves protocol compatibility between Go and Rust implementations.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix delete endpoint to return 200 OK with JSON response
- Changed handleKillSession to return 200 OK instead of 204 No Content
- Added JSON response with success/message fields for consistency
- Fixes benchmark tool compatibility expecting 200 response
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Update Go server API to match Rust format exactly
- Use 'command' array instead of 'cmdline'
- Use 'workingDir' instead of 'cwd'
- Remove compatibility shims for cleaner API
- Better error messages matching Rust server
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Major performance optimizations for Go server
- Remove 100ms artificial delay in session creation (-100ms per session)
- Optimize PTY I/O handling with reduced polling intervals
- Implement persistent stdin pipes to avoid repeated open/close
- Batch file sync operations to reduce I/O overhead (5ms batching)
- Remove blocking status updates from API handlers
- Increase SSE session check interval from 100ms to 1s
Target: Match Rust performance (60ms avg latency, 16+ ops/sec)
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix O_NONBLOCK compilation issue
* Add comprehensive TLS/HTTPS support with Caddy integration
Features:
- Optional TLS support via CLI flags (defaults to HTTP like Rust)
- Self-signed certificate generation for localhost development
- Let's Encrypt automatic certificate management for domains
- Custom certificate support for production environments
- HTTP to HTTPS redirect capability
- Maintains 100% backward compatibility with Rust version
Usage examples:
- Default HTTP: ./vibetunnel --serve (same as Rust)
- HTTPS with self-signed: ./vibetunnel --serve --tls
- HTTPS with domain: ./vibetunnel --serve --tls --tls-domain example.com
- HTTPS with custom certs: ./vibetunnel --serve --tls --tls-cert cert.pem --tls-key key.pem
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Fix terminal sizing issues and implement dynamic resize support
Backend changes:
- Add handleResizeSession API endpoint for dynamic terminal resizing
- Implement Session.Resize() and PTY.Resize() methods with proper validation
- Add session registry in Manager to track running sessions with PTY access
- Fix stdin error handling to prevent session crashes on EAGAIN errors
- Write resize events to asciinema stream for frontend synchronization
- Update default terminal dimensions from 80x24 to 120x30
Frontend changes:
- Add width/height parameters to SessionCreateData interface
- Calculate appropriate terminal dimensions when creating sessions
- Implement automatic resize API calls when terminal dimensions change
- Add terminal-resize event dispatch for backend synchronization
- Ensure resize events bubble properly for session management
Fixes nvim being stuck at 80x24 by implementing proper terminal
dimension management and dynamic resizing capabilities.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Add client-side resize caching and Hack Nerd Font support
- Implement resize request caching to prevent redundant API calls
- Add debouncing to terminal resize events (250ms delay)
- Replace ResizeObserver with window.resize events only to eliminate pixel-level jitter
- Add Hack Nerd Font Mono as primary terminal font with Fira Code fallback
- Update session creation to use conservative 120x30 defaults
- Fix terminal dimension calculation in normal mode
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
* Add comprehensive XTerm color and rendering enhancements
- Complete 256-color palette support with CSS variables (0-255)
- Enhanced XTerm configuration with proper terminal options
- True xterm-compatible 16-color theme
- Text attribute support: bold, italic, underline, dim, strikethrough, inverse, invisible
- Cursor blinking with CSS animation
- Font rendering optimizations (disabled ligatures, antialiasing)
- Terminal-specific CSS styling for better rendering
- Mac option key as meta, alt-click cursor movement
- Selection colors and inactive selection support
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude <noreply@anthropic.com>
- Remove automatic session snapshot loading on exit in session-view
- Update cast-converter to properly parse exit events in new format
- Handle exit events when timestamp field is "exit" string
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add HTML escaping to prevent HTML injection in terminal output
- Implement smart follow cursor with programmatic scroll protection
- Add output batching for SSE streams (~60fps) to improve performance
- Use integer pixel positions for crisp text rendering
- Preserve .vibetunnel folder contents on server restart
- Restrict mobile keyboard to actual mobile devices only
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Changed from single large write to batched writes (~1MB per batch)
- Prevents "write data discarded, use flow control" errors
- Flushes batches before resize events to maintain proper sequence
- Balances performance with buffer limits for reliable data transfer
- Handles large session dumps without data loss
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Added connectToStream() method that connects terminal to SSE streams
- Handles header messages with terminal dimensions for initial sizing
- Processes cast events for output ('o') and resize ('r') operations
- Detects session exit events and cleans up connections automatically
- Dispatches custom events for terminal-resize and session-exit
- Returns connection object with EventSource and disconnect method for cleanup
- Uses followCursor=true for live streaming vs false for dumps
- Comprehensive error handling and connection state management
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Added dumpToTerminal() method that builds entire cast content into one string and writes it all at once for maximum performance
- Handles resize ('r') events by tracking final terminal dimensions and applying them before writing content
- Processes output ('o') events into a single concatenated string for the fastest possible loading
- Ignores input ('i') events during dump as they're not needed for display
- Updated session cards to use the new fast dump method instead of manual parsing
- Results in dramatically faster session card loading and refresh
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Removed console.log statements from viewportY setter, fitTerminal, setupResize, scrollViewportPixels, momentum scrolling, renderBuffer, scrollToBottom, and followCursor methods
- Cleaned up terminal creation logging
- Improved color handling to support 24-bit RGB colors and RGB objects
- Enhanced write method with followCursor parameter for better cursor tracking
- Added followCursor method for automatic cursor visibility during playback
- Updated test page with cast file playback functionality
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Replace non-null assertions with proper null checks in terminal.ts
- Add defensive null checks in all queued operations
- Fix non-null assertion in url-highlighter.ts regex match
- Remove all forbidden non-null assertion warnings for our files
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Extract URL detection and highlighting logic from terminal.ts into UrlHighlighter utility class
- Move all URL processing methods (processLinks, createUrlLinks, getLineText, createClickableInLine, wrapTextInClickable) to new file
- Keep terminal.ts focused on core terminal functionality
- Maintain all existing URL highlighting functionality including multi-line URL support
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>