Skip to content

WebSocket API Reference

AI Code UI uses WebSocket connections for real-time communication. This document describes the WebSocket protocol and message formats.

WebSocket Endpoints

Endpoint Purpose
/ws Chat messages and AI interactions
/shell Interactive terminal (PTY) sessions

Connection

Chat WebSocket (/ws)

const ws = new WebSocket('ws://localhost:3001/ws');

ws.onopen = () => {
  console.log('Connected to chat WebSocket');
};

ws.onmessage = (event) => {
  const message = JSON.parse(event.data);
  // Handle message
};

ws.onerror = (error) => {
  console.error('WebSocket error:', error);
};

ws.onclose = () => {
  console.log('WebSocket closed');
};

Shell WebSocket (/shell)

const shell = new WebSocket('ws://localhost:3001/shell');

shell.onopen = () => {
  // Initialize terminal session
  shell.send(JSON.stringify({
    type: 'init',
    projectPath: '/path/to/project',
    sessionId: 'session-id',
    provider: 'claude'
  }));
};

Chat WebSocket Messages

Client → Server

Start Claude Session

{
  "type": "claude-command",
  "command": "start",
  "options": {
    "projectPath": "/path/to/project",
    "sessionId": "session-id",
    "prompt": "User message",
    "model": "claude-sonnet-4-5-20250929",
    "contextWindow": 160000
  }
}

Start Cursor Session

{
  "type": "cursor-command",
  "command": "start",
  "options": {
    "projectPath": "/path/to/project",
    "sessionId": "session-id",
    "prompt": "User message",
    "model": "gpt-5.2"
  }
}

Start Codex Session

{
  "type": "codex-command",
  "command": "start",
  "options": {
    "projectPath": "/path/to/project",
    "sessionId": "session-id",
    "prompt": "User message",
    "model": "gpt-5.2"
  }
}

Abort Session

{
  "type": "abort-session",
  "sessionId": "session-id",
  "provider": "claude|cursor|codex"
}

Permission Response (Claude)

{
  "type": "claude-permission-response",
  "requestId": "request-id",
  "allow": true,
  "remember": false
}

Continue Conversation

{
  "type": "continue",
  "sessionId": "session-id",
  "provider": "claude"
}

Server → Client

Claude Response Events

{
  "type": "claude-response",
  "data": {
    "type": "text",
    "content": "AI response text"
  }
}
{
  "type": "claude-response",
  "data": {
    "type": "tool_use",
    "tool": "bash",
    "input": {
      "command": "ls -la"
    }
  }
}
{
  "type": "claude-response",
  "data": {
    "type": "tool_result",
    "tool": "bash",
    "output": "file1.js\nfile2.js"
  }
}

Permission Request (Claude)

{
  "type": "claude-permission-request",
  "requestId": "request-id",
  "tool": "bash",
  "input": {
    "command": "rm -rf node_modules"
  },
  "description": "Execute bash command"
}

Cursor Response Events

{
  "type": "cursor-response",
  "data": {
    "type": "text",
    "content": "AI response text"
  }
}

Codex Response Events

{
  "type": "codex-response",
  "data": {
    "type": "text",
    "content": "AI response text"
  }
}

Session Events

{
  "type": "session-started",
  "sessionId": "session-id",
  "provider": "claude"
}
{
  "type": "session-ended",
  "sessionId": "session-id",
  "provider": "claude",
  "reason": "completed|aborted|error"
}

Error Events

{
  "type": "error",
  "error": "Error message",
  "code": "ERROR_CODE"
}

Projects Updated

{
  "type": "projects-updated",
  "projects": [
    {
      "path": "/path/to/project",
      "name": "project-name",
      "sessions": []
    }
  ]
}

Token Usage

{
  "type": "token-usage",
  "usage": {
    "inputTokens": 1000,
    "outputTokens": 500,
    "totalTokens": 1500,
    "contextWindow": 160000
  }
}

Shell WebSocket Messages

Client → Server

Initialize Terminal

{
  "type": "init",
  "projectPath": "/path/to/project",
  "sessionId": "session-id",
  "provider": "claude"
}

Send Input

{
  "type": "input",
  "data": "ls -la\n"
}

Resize Terminal

{
  "type": "resize",
  "cols": 120,
  "rows": 30
}

Server → Client

Terminal Output

{
  "type": "output",
  "data": "terminal output data"
}

Terminal Ready

{
  "type": "ready"
}

Terminal Error

{
  "type": "error",
  "error": "Error message"
}

Terminal Exit

{
  "type": "exit",
  "code": 0
}

Event Flow Examples

Complete Chat Flow

Client                          Server                          AI Provider
   │                               │                                  │
   │ claude-command (start)        │                                  │
   ├──────────────────────────────►│                                  │
   │                               │ Start session                    │
   │                               ├─────────────────────────────────►│
   │                               │                                  │
   │                               │ Stream: text                     │
   │                               │◄─────────────────────────────────┤
   │ claude-response (text)        │                                  │
   │◄──────────────────────────────┤                                  │
   │                               │                                  │
   │                               │ Stream: tool_use                 │
   │                               │◄─────────────────────────────────┤
   │ claude-permission-request     │                                  │
   │◄──────────────────────────────┤                                  │
   │                               │                                  │
   │ claude-permission-response    │                                  │
   ├──────────────────────────────►│                                  │
   │                               │ Execute tool                     │
   │                               ├─────────────────────────────────►│
   │                               │                                  │
   │                               │ Stream: tool_result              │
   │                               │◄─────────────────────────────────┤
   │ claude-response (tool_result) │                                  │
   │◄──────────────────────────────┤                                  │
   │                               │                                  │
   │                               │ Stream: end                      │
   │                               │◄─────────────────────────────────┤
   │ session-ended                 │                                  │
   │◄──────────────────────────────┤                                  │

Tool Approval Flow

Client                          Server
   │                               │
   │                               │ Tool requires approval
   │                               │
   │ claude-permission-request     │
   │◄──────────────────────────────┤
   │                               │
   │ [User reviews in UI]          │
   │                               │
   │ claude-permission-response    │
   │ {allow: true, remember: true} │
   ├──────────────────────────────►│
   │                               │
   │                               │ Execute tool
   │                               │ (future uses auto-approved)

Connection Management

Reconnection Strategy

The frontend implements automatic reconnection:

// From src/utils/websocket.js
const RECONNECT_DELAY = 1000;
const MAX_RECONNECT_DELAY = 30000;

function reconnect() {
  const delay = Math.min(
    RECONNECT_DELAY * Math.pow(2, reconnectAttempts),
    MAX_RECONNECT_DELAY
  );

  setTimeout(() => {
    connect();
    reconnectAttempts++;
  }, delay);
}

Heartbeat

The server sends periodic heartbeat messages:

{
  "type": "heartbeat",
  "timestamp": 1704067200000
}

Clients should respond within 30 seconds or the connection may be terminated.


Error Handling

Error Message Format

{
  "type": "error",
  "error": "Human-readable error message",
  "code": "ERROR_CODE",
  "details": {
    "field": "additional context"
  }
}

Common Error Codes

Code Description
INVALID_MESSAGE Malformed message format
UNKNOWN_COMMAND Unrecognized message type
SESSION_NOT_FOUND Session doesn't exist
PROVIDER_ERROR AI provider returned error
PERMISSION_DENIED Tool execution denied
TIMEOUT Operation timed out
CONNECTION_ERROR Connection-related error

Best Practices

Message Handling

  1. Always validate message types before processing
  2. Handle unknown message types gracefully
  3. Implement timeout handling for requests
  4. Buffer messages during reconnection

Performance

  1. Avoid sending large payloads (>1MB)
  2. Implement client-side rate limiting
  3. Use message batching when appropriate
  4. Clean up listeners on disconnect

Security

  1. Validate all incoming messages
  2. Sanitize user input before sending
  3. Don't trust client-provided session IDs
  4. Implement proper authentication