Ctrl + K

WebSocket

Real-time communication with your sandbox environment through WebSocket connections. Use this for interactive terminals and file watching.

Overview

The SDK automatically manages WebSocket connections for you. When you use real-time features like terminals or file watching, the connection is established automatically.

Real-Time Terminal

Create interactive terminal sessions:

// Create terminal - WebSocket auto-connects
const terminal = await sandbox.terminal.create({
  cols: 120,
  rows: 30,
  cwd: '/opt/app',
  onData: (data) => {
    console.log(data); // Real-time output
  },
  onExit: (code, signal) => {
    console.log('Terminal exited:', code);
  }
});

// Execute commands
terminal.write('npm install\n');
terminal.write('npm run dev\n');

// Get terminal state (history)
const state = await terminal.getState({
  newOnly: false,
  maxLines: 100
});

// Decode output
const output = Buffer.from(state, 'base64').toString('utf-8');
console.log(output);

// Resize terminal
await terminal.resize(150, 40);

// Close terminal
await terminal.close();

WebSocket connection with query parameter:

const ws = new WebSocket(
  `wss://${sandbox.url.replace('https://', '')}/ws?token=${sandbox.token}`
);

ws.onopen = () => {
  // Create terminal
  ws.send(JSON.stringify({
    action: 'terminal_create',
    terminalId: 1,
    cols: 120,
    rows: 30,
    cwd: '/opt/app'
  }));
};

ws.onmessage = (event) => {
  const message = JSON.parse(event.data);
  
  if (message.type === 'terminal_data') {
    const output = Buffer.from(message.data, 'base64').toString('utf-8');
    console.log(output);
  }
  
  if (message.type === 'terminal_exit') {
    console.log('Exit code:', message.code);
  }
};

// Write to terminal
ws.send(JSON.stringify({
  action: 'terminal_data',
  terminalId: 1,
  data: Buffer.from('npm install\n').toString('base64')
}));

WebSocket requires a WebSocket client. Using websocat:

# Install websocat first: https://github.com/vi/websocat
# Connect to WebSocket
websocat "wss://sandbox.oblien.com/?token=YOUR_SANDBOX_TOKEN"

# Once connected, send JSON messages:
# Create terminal:
{"action":"terminal_create","terminalId":1,"cols":120,"rows":30,"cwd":"/opt/app"}

# Write to terminal (data must be base64):
{"action":"terminal_data","terminalId":1,"data":"bnBtIGluc3RhbGwK"}

Terminal Parameters

ParameterTypeDefaultDescription
terminalIdnumberautoTerminal ID
colsnumber120Terminal columns
rowsnumber30Terminal rows
cwdstring/opt/appWorking directory
commandstring-Initial command
argsstring[][]Command arguments
taskbooleanfalseRun as task (one-off)
onDatafunction-Data callback
onExitfunction-Exit callback

List Terminals

const terminals = await sandbox.terminal.list();

console.log('Active terminals:', terminals);
terminals.forEach(t => {
  console.log(`Terminal ${t.id}`);
});
ws.send(JSON.stringify({
  action: 'terminal_list'
}));

// Response in ws.onmessage:
// { type: 'terminal_list', terminals: [...] }
# Using websocat
websocat "wss://sandbox.oblien.com/?token=YOUR_SANDBOX_TOKEN"

# Send list command:
{"action":"terminal_list"}

# Response: {"type":"terminal_list","terminals":[...]}

Complete Terminal Example

// Create interactive terminal
const terminal = await sandbox.terminal.create({
  cols: 120,
  rows: 30,
  cwd: '/opt/app',
  onData: (data) => {
    // Stream output to console
    process.stdout.write(data);
  },
  onExit: (code, signal) => {
    console.log(`\nTerminal exited with code ${code}`);
  }
});

console.log(`Created terminal ${terminal.id}`);

// Run commands
terminal.write('npm install\n');

// Wait a bit for install to complete
await new Promise(resolve => setTimeout(resolve, 10000));

// Run development server
terminal.write('npm run dev\n');

// Listen for specific output
terminal.onData((data) => {
  if (data.includes('Server running')) {
    console.log('Server started successfully!');
  }
});

// Get full terminal history
const history = await terminal.getState();
const output = Buffer.from(history, 'base64').toString('utf-8');
console.log('Terminal output:', output);

// Keep terminal running...
// Later, close it
await terminal.close();
const ws = new WebSocket(
  `wss://${sandbox.url.replace('https://', '')}/ws?token=${sandbox.token}`
);

let terminalId = 1;

ws.onopen = () => {
  // Create terminal
  ws.send(JSON.stringify({
    action: 'terminal_create',
    terminalId,
    cols: 120,
    rows: 30,
    cwd: '/opt/app'
  }));
  
  // Send commands
  setTimeout(() => {
    ws.send(JSON.stringify({
      action: 'terminal_data',
      terminalId,
      data: Buffer.from('npm install\n').toString('base64')
    }));
  }, 1000);
};

ws.onmessage = (event) => {
  const message = JSON.parse(event.data);
  
  if (message.type === 'terminal_data') {
    const output = Buffer.from(message.data, 'base64').toString('utf-8');
    console.log(output);
  }
  
  if (message.type === 'terminal_exit') {
    console.log('Terminal exited:', message.code);
  }
};

// Close terminal
ws.send(JSON.stringify({
  action: 'terminal_close',
  terminalId
}));
# Using websocat for interactive terminal
websocat "wss://sandbox.oblien.com/?token=YOUR_SANDBOX_TOKEN"

# Create terminal:
{"action":"terminal_create","terminalId":1,"cols":120,"rows":30,"cwd":"/opt/app"}

# Write commands (base64 encoded):
{"action":"terminal_data","terminalId":1,"data":"bnBtIGluc3RhbGwK"}

# Close terminal:
{"action":"terminal_close","terminalId":1}

Execute One-Off Command

For simple command execution without interactive terminal:

// Using terminal manager (WebSocket-based)
const result = await sandbox.terminal.execute({
  command: 'npm test',
  cwd: '/opt/app',
  timeout: 60000
});

console.log('Exit code:', result.exitCode);
console.log('Output:', result.logs);

WebSocket Events

Terminal Events

EventDescriptionData
terminal_dataTerminal output{ data: base64, terminalId }
terminal_exitTerminal closed{ code, signal, terminalId }
terminal_listList response{ terminals: [...] }

File Watcher Events

EventDescriptionData
watch_addFile added{ path }
watch_changeFile changed{ path }
watch_unlinkFile deleted{ path }
watch_errorWatch error{ path, error }

Connection Management

// SDK auto-manages connections

// Check connection status
if (sandbox.connected) {
  console.log('WebSocket connected');
}

// Manual connect (usually not needed)
await sandbox.connect();

// Manual disconnect
sandbox.disconnect();
const ws = new WebSocket(
  `wss://${sandbox.url.replace('https://', '')}/ws?token=${sandbox.token}`
);

ws.onopen = () => console.log('Connected');
ws.onclose = () => console.log('Disconnected');
ws.onerror = (error) => console.error('Error:', error);

// Close connection
ws.close();
# Using websocat
websocat "wss://sandbox.oblien.com/?token=YOUR_SANDBOX_TOKEN"

# Connection opens automatically
# Close with Ctrl+C or EOF

Best Practices

  1. Handle connection errors:

    terminal.onData((data) => {
      // Handle output
    });
  2. Clean up terminals: Always close terminals when done

  3. Use appropriate buffer sizes: Don't request too much terminal history

  4. Handle exit events: Listen for terminal exit to know when commands finish

  5. Resize terminals: Match terminal size to display area

Next Steps