No description
Find a file
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
.github Add iOS CI, fix Swift CI 2025-06-20 11:33:03 +02:00
AppIcon.icon Add new icon 2025-06-16 04:42:13 +02:00
assets Add frontend screenshot to README 2025-06-17 02:20:58 +02:00
benchmark Add comprehensive VibeTunnel protocol benchmark tool (#18) 2025-06-18 23:38:11 +02:00
docs Hummingbird removed 2025-06-20 07:00:00 +02:00
ios lint+format 2025-06-20 11:33:03 +02:00
linux fix: Go server CPU optimization & resize control flag (#32) 2025-06-20 11:37:54 +02:00
scripts Add support for go in Mac app, implement missing features 2025-06-19 23:44:28 +02:00
tty-fwd Fix Ctrl+C signal handling and cross-server session compatibility 2025-06-19 23:06:39 +02:00
VibeTunnel Remove Hummingbird 2025-06-20 06:59:17 +02:00
VibeTunnel.xcodeproj change build to copy vt script 2025-06-20 07:17:53 +02:00
VibeTunnel.xcworkspace Added --spawn-terminal experiment 2025-06-17 11:08:28 +02:00
VibeTunnelTests Remove Hummingbird 2025-06-20 06:59:17 +02:00
web feat: implement proper authentication with username/password support 2025-06-20 11:36:32 +02:00
.gitattributes Add .gitattributes to normalize line endings to LF 2025-06-19 17:44:30 +02:00
.github-config Add macOS app foundation with release infrastructure (#1) 2025-06-15 23:14:29 +02:00
.gitignore ignore vt binary 2025-06-20 07:17:22 +02:00
.swiftformat Update to version 1.0.0 build 100 and fix all linting issues 2025-06-16 23:45:44 +02:00
.swiftlint.yml Update to version 1.0.0 build 100 and fix all linting issues 2025-06-16 23:45:44 +02:00
API.md Fix cross-platform build issues in web package 2025-06-19 01:43:27 +02:00
appcast-prerelease.xml Fix appcast changelog extraction for beta releases 2025-06-19 15:00:21 +02:00
appcast.xml Update appcast for 1.0-beta.1 2025-06-17 03:09:23 +02:00
benchmark-streaming.js Add vibe-terminal-buffer component for efficient session previews 2025-06-20 02:19:09 +02:00
CHANGELOG.md Bump version to 1.0.0-beta.2 2025-06-19 02:51:22 +02:00
CLAUDE.md Remove lint_output.txt and add to gitignore 2025-06-19 00:57:31 +02:00
high-throughput-test.js Add vibe-terminal-buffer component for efficient session previews 2025-06-20 02:19:09 +02:00
KEYCHAIN_OPTIMIZATION.md Fix platform-specific CI issues 2025-06-17 01:45:07 +02:00
LICENSE Initial commit 2025-06-15 19:56:11 +02:00
Package.swift Remove Hummingbird 2025-06-20 06:59:17 +02:00
README.md docs: add Rust and Node.js prerequisites to build instructions 2025-06-19 01:45:00 +02:00
simple-test.js Add vibe-terminal-buffer component for efficient session previews 2025-06-20 02:19:09 +02:00
test-tty-fwd.swift update test 2025-06-17 01:29:57 +02:00
VibeTunnel-Info.plist prepare sparkle 2025-06-17 01:29:42 +02:00

VibeTunnel Banner

VibeTunnel

Turn any browser into your Mac terminal. VibeTunnel proxies your terminals right into the browser, so you can vibe-code anywhere.

Download License macOS 14.0+

Why VibeTunnel?

Ever wanted to check on your AI agents while you're away? Need to monitor that long-running build from your phone? Want to share a terminal session with a colleague without complex SSH setups? VibeTunnel makes it happen with zero friction.

"We wanted something that just works" - That's exactly what we built.

The Story

VibeTunnel was born from a simple frustration: checking on AI agents remotely was way too complicated. During an intense coding session, we decided to solve this once and for all. The result? A tool that makes terminal access as easy as opening a web page.

Read the full story: VibeTunnel: Turn Any Browser Into Your Mac Terminal

Key Features

  • 🌐 Browser-Based Access - Control your Mac terminal from any device with a web browser
  • 🚀 Zero Configuration - No SSH keys, no port forwarding, no complexity
  • 🤖 AI Agent Friendly - Perfect for monitoring Claude Code, ChatGPT, or any terminal-based AI tools
  • 🔒 Secure by Design - Password protection, localhost-only mode, or secure tunneling via Tailscale/ngrok
  • 📱 Mobile Ready - Check your terminals from your phone, tablet, or any computer
  • 🎬 Session Recording - All sessions are recorded in asciinema format for later playback

Quick Start

1. Download & Install

Download VibeTunnel and drag it to your Applications folder.

2. Launch VibeTunnel

VibeTunnel lives in your menu bar. Click the icon to start the server.

3. Use the vt Command

Prefix any command with vt to make it accessible in your browser:

# Monitor AI agents
vt claude

# Run development servers
vt npm run dev

# Watch long-running processes
vt python train_model.py

# Or just open a shell
vt --shell

4. Open Your Dashboard

VibeTunnel Frontend

Visit http://localhost:4020 to see all your terminal sessions in the browser.

Real-World Use Cases

🤖 AI Development

Monitor and control AI coding assistants like Claude Code remotely. Perfect for checking on agent progress while you're away from your desk.

vt claude --dangerously-skip-permissions

🛠️ Remote Development

Access your development environment from anywhere. No more "I need to check something on my work machine" moments.

vt code .
vt npm run dev

📊 System Monitoring

Keep an eye on system resources, logs, or long-running processes from any device.

vt htop
vt tail -f /var/log/system.log

🎓 Teaching & Collaboration

Share terminal sessions with colleagues or students in real-time through a simple web link.

Remote Access Options

  1. Install Tailscale on your Mac and remote device
  2. Access VibeTunnel at http://[your-mac-name]:4020 from anywhere on your Tailnet

Option 2: ngrok

  1. Add your ngrok auth token in VibeTunnel settings
  2. Enable ngrok tunneling
  3. Share the generated URL for remote access

Option 3: Local Network

  1. Set a dashboard password in settings
  2. Switch to "Network" mode
  3. Access via http://[your-mac-ip]:4020

Command Options

# Claude-specific shortcuts
vt --claude              # Auto-locate and run Claude
vt --claude-yolo         # Run Claude with dangerous permissions

# Shell options
vt --shell               # Launch interactive shell
vt -i                    # Short form for --shell

# Direct execution (bypasses shell aliases)
vt -S ls -la            # Execute without shell wrapper

Configuration

Access settings through the menu bar icon:

  • Server Port: Change the default port (4020)
  • Launch at Login: Start VibeTunnel automatically
  • Show in Dock: Toggle between menu bar only or dock icon
  • Server Mode: Switch between Rust (default) or Swift backend

Architecture

VibeTunnel is built with a modern, secure architecture:

  • Native macOS app written in Swift/SwiftUI
  • High-performance Rust server for terminal management
  • Web interface with real-time terminal rendering
  • Secure tunneling via Tailscale or ngrok

For technical details, see ARCHITECTURE.md.

Building from Source

Prerequisites

  • Rust: Install via https://rustup.sh/
    # After installing Rust, add the x86_64 target for universal binary support
    rustup target add x86_64-apple-darwin
    
  • Node.js: Required for building the web frontend

Build Steps

# Clone the repository
git clone https://github.com/amantus-ai/vibetunnel.git
cd vibetunnel

# Build the Rust server
cd tty-fwd && cargo build --release && cd ..

# Build the web frontend
cd web && npm install && npm run build && cd ..

# Open in Xcode
open VibeTunnel.xcodeproj

Local Development Setup

For local development, configure your development team ID in Local.xcconfig. Without this, you'll face repeated permission and keychain dialogs, especially with ad-hoc installations. With proper code signing, these dialogs only appear on first launch.

To get your team ID:

security find-identity -v -p codesigning

Then copy Local.xcconfig.template to Local.xcconfig and insert your team ID. This file is gitignored to keep your personal settings private.

Credits

Created with ❤️ by:

Contributing

We welcome contributions! Please see our Contributing Guide for details.

License

VibeTunnel is open source software licensed under the MIT License. See LICENSE for details.


Ready to vibe? Download VibeTunnel and start tunneling!