# VibeTunnel Socket Protocol ## Overview VibeTunnel uses a binary framed message protocol over Unix domain sockets for all inter-process communication (IPC). This protocol replaces the previous file-based IPC system, providing better performance, real-time updates, and cleaner architecture. ## Architecture ### Components 1. **PTY Manager** (Server) - Creates Unix domain socket at `{session_dir}/ipc.sock` - Handles multiple client connections - Manages PTY process I/O - Tracks session state and Claude status 2. **Socket Client** (fwd.ts and other clients) - Connects to session's Unix socket - Sends stdin data and control commands - Receives status updates and errors - Supports auto-reconnection ### Socket Path - Location: `{control_dir}/{session_id}/ipc.sock` - Example: `/tmp/vt-1234567890/a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6/ipc.sock` **Important**: macOS has a 104 character limit for Unix socket paths (103 usable). Keep control directories short to avoid EINVAL errors. ## Message Format ### Frame Structure ``` +--------+--------+--------+--------+--------+----------------+ | Type | Length | Payload | | 1 byte | 4 bytes (big-endian uint32) | Length bytes | +--------+--------+--------+--------+--------+----------------+ ``` - **Type**: Single byte indicating message type - **Length**: 32-bit unsigned integer in big-endian format - **Payload**: Variable-length data (format depends on message type) ### Message Types | Type | Value | Direction | Description | |------|-------|-----------|-------------| | STDIN_DATA | 0x01 | Client → Server | Terminal input data | | CONTROL_CMD | 0x02 | Client → Server | Control commands (resize, kill) | | STATUS_UPDATE | 0x03 | Both | Activity status updates | | HEARTBEAT | 0x04 | Both | Connection health check | | ERROR | 0x05 | Server → Client | Error messages | ## Message Payloads ### STDIN_DATA (0x01) - **Payload**: UTF-8 encoded string - **Example**: `"ls -la\n"` ### CONTROL_CMD (0x02) - **Payload**: JSON object - **Commands**: ```json // Resize terminal { "cmd": "resize", "cols": 120, "rows": 40 } // Kill process { "cmd": "kill", "signal": "SIGTERM" } // Reset terminal size { "cmd": "reset-size" } ``` ### STATUS_UPDATE (0x03) - **Payload**: JSON object - **Format**: ```json { "app": "claude", "status": "✻ Thinking (5s, ↑2.5k tokens)", // Optional extra fields "tokens": 2500, "duration": 5000 } ``` - **Broadcast**: Server broadcasts status updates to all connected clients ### HEARTBEAT (0x04) - **Payload**: Empty (0 bytes) - **Behavior**: - Clients can send periodic heartbeats - Server echoes heartbeats back - Used to detect connection health ### ERROR (0x05) - **Payload**: JSON object - **Format**: ```json { "code": "SESSION_NOT_FOUND", "message": "Session does not exist", "details": { /* optional */ } } ``` #### Error Codes | Code | Description | Details | |------|-------------|---------| | `SESSION_NOT_FOUND` | The requested session does not exist | Session ID is invalid or session has been terminated | | `MESSAGE_PROCESSING_ERROR` | Failed to process incoming message | Malformed message, invalid JSON, or internal processing error | | `INVALID_OPERATION` | Operation not valid for session type | e.g., reset-size on in-memory session | | `CONTROL_MESSAGE_FAILED` | Failed to send control message | Unable to communicate with PTY process | | `RESET_SIZE_FAILED` | Failed to reset terminal size | Error during size reset operation | | `CONNECTION_LIMIT` | Too many concurrent connections | Server connection limit reached | | `PAYLOAD_TOO_LARGE` | Message payload exceeds size limit | Payload larger than maximum allowed size | | `INVALID_MESSAGE_TYPE` | Unknown or unsupported message type | Client sent unrecognized message type | | `MALFORMED_FRAME` | Invalid message frame structure | Message framing protocol violation | **Example Error Response**: ```json { "code": "MESSAGE_PROCESSING_ERROR", "message": "Failed to parse control command", "details": { "error": "Unexpected token } in JSON at position 42", "messageType": 2 } } ``` ## Client Implementation ### Connection Flow 1. Connect to Unix socket at `{session_dir}/ipc.sock` 2. Receive any initial status updates from server 3. Send messages as needed 4. Handle incoming messages asynchronously 5. Reconnect automatically on disconnection (optional) ### Example Usage ```typescript import { VibeTunnelSocketClient } from './socket-client.js'; // Connect to session const client = new VibeTunnelSocketClient('/path/to/session/ipc.sock', { autoReconnect: true, heartbeatInterval: 30000 // 30 seconds }); // Listen for events client.on('connect', () => console.log('Connected')); client.on('status', (status) => console.log('Status:', status)); client.on('error', (err) => console.error('Error:', err)); // Connect and use await client.connect(); // Send terminal input client.sendStdin('echo "Hello, World!"\n'); // Resize terminal client.resize(120, 40); // Send Claude status client.sendStatus('claude', '✻ Thinking', { tokens: 1000 }); // Disconnect when done client.disconnect(); ``` ## Server Implementation ### Socket Server Setup The PTY manager creates a Unix domain socket for each session: ```typescript // Create socket server const server = net.createServer((client) => { const parser = new MessageParser(); // Send initial status if available if (claudeStatus) { client.write(frameMessage(MessageType.STATUS_UPDATE, claudeStatus)); } // Handle incoming messages client.on('data', (chunk) => { parser.addData(chunk); for (const { type, payload } of parser.parseMessages()) { handleMessage(type, payload, client); } }); }); // Listen on socket server.listen(socketPath); ``` ### Message Handling The server processes messages based on type: - **STDIN_DATA**: Write to PTY process - **CONTROL_CMD**: Handle resize/kill commands - **STATUS_UPDATE**: Store status and broadcast to other clients - **HEARTBEAT**: Echo back to sender ## Protocol Features ### Message Framing The protocol handles: - **Partial messages**: TCP may split messages across packets - **Multiple messages**: TCP may combine messages in one packet - **Large payloads**: No practical size limit (up to 4GB per message) - **Binary safety**: Handles null bytes and non-UTF8 data ### Connection Management - **Multiple clients**: Server supports multiple simultaneous connections - **Auto-reconnection**: Clients can automatically reconnect on failure - **Heartbeats**: Optional periodic heartbeats for connection health - **Graceful shutdown**: Proper cleanup of resources ### Status Broadcasting When a client sends a STATUS_UPDATE: 1. Server stores the status in memory 2. Server broadcasts to all other connected clients 3. New clients receive current status on connection ## Migration from File-Based IPC ### Previous System - Control commands via `{session_dir}/control-pipe` file - Activity updates via `{session_dir}/activity.json` file - Required file watching and polling ### New System - All communication through single Unix socket - Real-time bidirectional messaging - No file watching or polling needed - Better performance and cleaner architecture ## Error Handling ### Connection Errors - **ENOENT**: Socket file doesn't exist (session not found) - **ECONNREFUSED**: Server not listening (session crashed) - **EINVAL**: Socket path too long (macOS limit) ### Protocol Errors - Malformed messages are logged and ignored - Server sends ERROR message for processing failures - Clients should handle disconnections gracefully ## Performance Considerations 1. **Message Size**: Keep messages reasonably sized (< 1MB) 2. **Heartbeat Interval**: 30-60 seconds is typical 3. **Reconnect Delay**: 1-5 seconds between attempts 4. **Socket Backlog**: Default is sufficient for typical usage ## Security Notes - Sockets are created with 0666 permissions (world-writable) - Rely on directory permissions for access control - No authentication or encryption (local use only) - Validate all JSON payloads before processing ## Implementation Files - **Protocol**: `src/server/pty/socket-protocol.ts` - **Client**: `src/server/pty/socket-client.ts` - **Server**: `src/server/pty/pty-manager.ts` (setupIPCSocket method) - **Tests**: `src/test/unit/socket-*.test.ts`, `src/test/integration/socket-*.test.ts` ## Future Enhancements Potential improvements to consider: - Message compression for large payloads - Authentication for multi-user systems - Encryption for sensitive data - Request/response correlation IDs - Batch message support