• English
  • WebTerminal Integration

    AIO Sandbox provides a built-in Web Terminal page and exposes a Shell WebSocket endpoint so you can embed a terminal in your own local web UI.

    The examples below assume AIO Sandbox is running at http://localhost:8080.

    Built-In Terminal Page

    Open:

    http://localhost:8080/terminal

    The page loads the xterm.js assets bundled inside the sandbox:

    /static/sandbox/xterm@5.3.0/
    /static/sandbox/xterm-addon-fit@0.8.0/

    Local previews do not depend on an external CDN. The page connects to ws://localhost:8080/v1/shell/ws, creates a new terminal session, and writes the returned session_id into the URL so the UI can identify the active session.

    WebSocket Endpoint

    Connect your custom UI to a new session:

    ws://localhost:8080/v1/shell/ws

    After the connection is established, the server returns a session_id so your UI can identify the active session. After connection failures, create a new terminal session instead of relying on ws?session_id=... for disconnect recovery or history restoration.

    Message Types

    Client to server:

    { "type": "input", "data": "ls -la\n" }
    { "type": "resize", "data": { "cols": 120, "rows": 40 } }
    { "type": "pong", "data": { "timestamp": 1710000000000 } }

    Server to client:

    { "type": "session_id", "data": "SESSION_ID" }
    { "type": "ready", "data": "Terminal ready" }
    { "type": "output", "data": "command output" }
    { "type": "ping", "timestamp": 1710000000000 }

    input is the raw terminal input stream, so include a newline when executing commands. Send resize when the terminal container changes size. Only reply with pong after receiving an application-level ping.

    Minimal Browser Example

    This example loads xterm.js from AIO's bundled static assets and connects a local page to a local sandbox.

    <!doctype html>
    <html>
      <head>
        <meta charset="utf-8" />
        <link
          rel="stylesheet"
          href="http://localhost:8080/static/sandbox/xterm@5.3.0/css/xterm.css"
        />
        <style>
          html,
          body,
          #terminal {
            width: 100%;
            height: 100%;
            margin: 0;
          }
        </style>
      </head>
      <body>
        <div id="terminal"></div>
    
        <script src="http://localhost:8080/static/sandbox/xterm@5.3.0/lib/xterm.js"></script>
        <script src="http://localhost:8080/static/sandbox/xterm-addon-fit@0.8.0/lib/xterm-addon-fit.js"></script>
        <script>
          const term = new Terminal({ cursorBlink: true, convertEol: true });
          const fitAddon = new FitAddon.FitAddon();
          term.loadAddon(fitAddon);
          term.open(document.getElementById("terminal"));
          fitAddon.fit();
    
          const ws = new WebSocket("ws://localhost:8080/v1/shell/ws");
    
          ws.addEventListener("open", () => {
            ws.send(JSON.stringify({
              type: "resize",
              data: { cols: term.cols, rows: term.rows },
            }));
          });
    
          term.onData((data) => {
            ws.send(JSON.stringify({ type: "input", data }));
          });
    
          ws.addEventListener("message", (event) => {
            const message = JSON.parse(event.data);
    
            if (message.type === "output") {
              term.write(message.data);
            }
    
            if (message.type === "ping") {
              ws.send(JSON.stringify({
                type: "pong",
                data: { timestamp: message.timestamp ?? message.data },
              }));
            }
          });
    
          window.addEventListener("resize", () => {
            fitAddon.fit();
            ws.send(JSON.stringify({
              type: "resize",
              data: { cols: term.cols, rows: term.rows },
            }));
          });
        </script>
      </body>
    </html>

    For the complete Shell protocol, see Shell Terminal.