Commit graph

35 commits

Author SHA1 Message Date
Peter Steinberger
e43ef5ad49 implement binary protocol, reduce buffers, fixes an echo race 2025-06-20 20:49:02 +02:00
Peter Steinberger
acadb6d6d8 kill echo, less chaos 2025-06-20 20:16:59 +02:00
Peter Steinberger
8bea2c87f6 better session management 2025-06-20 20:16:46 +02:00
Peter Steinberger
35bc91e0de execute commands through zsh 2025-06-20 20:16:30 +02:00
Peter Steinberger
8b64f2088d For spawned sessions, don't start the PTY immediately 2025-06-20 20:06:25 +02:00
Peter Steinberger
12ce2cd834 smaller buffer and flush 2025-06-20 20:02:52 +02:00
Peter Steinberger
22eb5a2e3f Work on new session logic 2025-06-20 19:22:02 +02:00
Peter Steinberger
35c2908a57 Improve error logging 2025-06-20 19:03:40 +02:00
Peter Steinberger
e7636dd039 revert: remove direct buffer integration feature 2025-06-20 18:54:06 +02:00
Peter Steinberger
bf31a85198 Execute through shell for propper command expansion 2025-06-20 18:32:15 +02:00
Peter Steinberger
b2cbb02bfd add direct buffer feature 2025-06-20 18:31:46 +02:00
Peter Steinberger
6e2cd2abcd fix: Run gofmt on terminal files to fix formatting 2025-06-20 16:29:56 +02:00
Peter Steinberger
709330ccde fix: Add platform-specific terminal constants for cross-platform build
- Create terminal_darwin.go with macOS-specific TIOCGETA/TIOCSETA
- Create terminal_linux.go with Linux-specific TCGETS/TCSETS
- Create terminal_other.go with fallback for other Unix systems
- Update terminal.go to use platform-specific constants
2025-06-20 16:26:41 +02:00
Peter Steinberger
20395d6e09 fix: Fix CI test failures
- Fix hanging TestNewStdinWatcher by not calling Stop() without Start()
- Fix TestSession_Signal and TestSession_KillWithSignal by adding PID values
- Fix isProcessRunning to use syscall.Signal(0) instead of os.Signal(nil)
- Update websocket test to expect new 'Unknown WebSocket endpoint' error message
- Add timeout handling to websocket integration test
2025-06-20 16:21:27 +02:00
Peter Steinberger
08bdc5ecb4 broader support for SetDoNotAllowColumnSet + tests 2025-06-20 16:01:38 +02:00
Peter Steinberger
70f5bf2c18 linting and test fixes 2025-06-20 15:43:06 +02:00
Peter Steinberger
b751dabd36 fix: Run gofmt to fix CI formatting errors
Applied gofmt to fix formatting issues in:
- pkg/api/websocket.go: Remove trailing whitespace
- pkg/session/pty.go: Remove trailing whitespace
2025-06-20 15:23:27 +02:00
Peter Steinberger
bec49c86e1 feat(cli): Improve CLI installation to copy both vt and vibetunnel
- Update CLIInstaller to install both vt script and vibetunnel binary
- Remove duplicate replacement dialog for better UX
- Check versions of both files and use lowest version for updates
- Prioritize finding vibetunnel in same directory as vt script
- Bump vt version to 1.0.6
- Add comprehensive CLI versioning documentation
2025-06-20 15:22:37 +02:00
Peter Steinberger
f96b63c77d Port node implementation details to go 2025-06-20 15:11:26 +02:00
Peter Steinberger
d0e92ea932 Tweaks from the rust implementation 2025-06-20 14:19:56 +02:00
Peter Steinberger
eced88b829 remove problematic code for terminal resize? 2025-06-20 13:57:16 +02:00
Helmut Januschka
afee29f2e3
fix: add missing newlines to platform-specific select files (#36)
- Add proper newlines at end of select_darwin.go and select_linux.go
- Resolves gofmt formatting issues in CI
- Ensures all Go files follow standard formatting conventions
2025-06-20 12:56:14 +02:00
Helmut Januschka
766147073b
fix: update Go CI workflow and fix formatting issues (#35)
* fix: update Go CI workflow and fix formatting issues

- Update Go version from 1.21.x to 1.24.x to match go.mod requirements
- Fix Go module cache path to use linux/go.sum instead of **/go.sum
- Run gofmt on all Go files to fix formatting issues
- Fix benchmark files formatting
- Fix linux/pkg/api/server.go formatting

This resolves the GitHub Actions CI failures related to:
- Missing go.sum file (wrong cache path)
- Go version mismatch
- Code formatting violations

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>

* fix: add platform-specific syscall.Select wrappers for Linux/Darwin compatibility

- Create select_linux.go: handles syscall.Select returning (n int, err error)
- Create select_darwin.go: handles syscall.Select returning (err error)
- Update select.go to use platform-agnostic selectCall function
- Resolves typecheck errors while maintaining compatibility on both platforms

Tested on both macOS and Linux targets successfully.

---------

Co-authored-by: Claude <noreply@anthropic.com>
2025-06-20 12:53:31 +02:00
Helmut Januschka
f758426ff4
fix: resolve golangci-lint issues and format Go code (#34)
- Run go fmt on all Go files (10 files formatted)
- Fix 50+ errcheck issues by adding proper error handling
- Fix 3 staticcheck issues (empty branches, error string capitalization)
- Remove 2 unused struct fields
- Install and configure golangci-lint v2.1.6 for Go 1.24 compatibility
- All linting now passes with 0 issues

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-06-20 12:43:59 +02:00
Helmut Januschka
70edaaddd5
feat: add cross-platform process checking with POSIX-first approach (#33)
**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>
2025-06-20 11:52:31 +02:00
Helmut Januschka
a66620be52
fix: Go server CPU optimization & resize control flag (#32)
* 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>
2025-06-20 11:37:54 +02:00
Peter Steinberger
aa60d9ef7d Validate that essential session files exist 2025-06-20 07:39:04 +02:00
Peter Steinberger
f40c4bc16f move closer to rust server format 2025-06-20 07:17:15 +02:00
Peter Steinberger
58fdc049ba copy more rust behavior, fix vt forwarder format 2025-06-20 05:30:13 +02:00
Peter Steinberger
c9b86bc9cf check if process is alve 2025-06-20 04:08:02 +02:00
Peter Steinberger
ca88128ff6 reap zombies 2025-06-20 04:08:02 +02:00
Peter Steinberger
8180586f2d terminal spawning, get rid of debug logs 2025-06-20 04:08:02 +02:00
Peter Steinberger
938682cc85 Make go serve via mac 2025-06-20 01:51:36 +02:00
Peter Steinberger
9c2c50dd4f Add support for go in Mac app, implement missing features 2025-06-19 23:44:28 +02:00
Helmut Januschka
b90bfd9f46
Add Go implementation of VibeTunnel server (#16)
* 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>
2025-06-18 23:32:35 +02:00