Skip to content

Getting Started

Environment requirements

  • Node.js >= 18 (see engines in package.json).
  • node-pty (required, the only backend, no fallback):
    • Linux: no prebuilt binary; it is compiled from source at install time and requires g++ with C++20 support (gcc-10 or newer).
    • Windows / macOS: prebuilt binaries are provided and work out of the box.
  • @xterm/headless (required): the screen-rendering backend, pure JS with no compile burden.

Installation

bash
npm install @ai-zen/socket-pty

To use it locally within the repo, build first and then consume via dist/:

bash
npm install
npm run build
node dist/cli.js serve --cmd bash --socket /tmp/x.sock

Quick examples

Start a service with the CLI

bash
# Unix domain socket (preferred on Linux/macOS)
socket-pty serve --cmd bash --socket /tmp/v.sock

# TCP loopback (preferred on Windows)
socket-pty serve --cmd bash --port 5174

# Windows: the .exe suffix is required
socket-pty serve --cmd powershell.exe --port 5174
socket-pty serve --cmd cmd.exe --port 5174

On successful startup it prints:

text
[socket-pty] 会话已启动,命令: bash
[socket-pty] 连接地址: 127.0.0.1:5174

Common serve options: --cmd (required), --socket / --port (choose one, one is required), --cols / --rows (default 100 / 30), --cwd.

Start programmatically

typescript
import { createSocketPty } from "@ai-zen/socket-pty";

const server = createSocketPty({
  endpoint: { type: "unix", path: "/tmp/v.sock" }, // or { type: "tcp", port: 5174, host: "127.0.0.1" }
  command: "bash", // on Windows use "powershell.exe" / "cmd.exe"
  cols: 100,
  rows: 30,
});
const address = await server.listen();
// address: unix:/tmp/v.sock

Connect and interact over JSON-RPC 2.0

Once connected, each line is one JSON-RPC 2.0 message, newline-delimited. The following uses bare JSON-RPC to read the terminal once:

jsonc
// Query status
→ {"jsonrpc":"2.0","method":"pty/status","params":{},"id":1}
← {"jsonrpc":"2.0","result":{"running":true,"exitCode":null,"pid":1234},"id":1}

// Write a command
→ {"jsonrpc":"2.0","method":"pty/write","params":{"action":[{"text":"echo hello"},{"key":"Enter"}]},"id":2}
← {"jsonrpc":"2.0","result":{"written":11},"id":2}

// Wait for output
→ {"jsonrpc":"2.0","method":"pty/wait","params":{"match":"hello","timeout":6000},"id":3}
← {"jsonrpc":"2.0","result":{"matched":true,"screen":"...","cursor":{"row":2,"col":1},"size":{"cols":100,"rows":30},"waitedMs":45},"id":3}

// Read the current screen
→ {"jsonrpc":"2.0","method":"pty/read","params":{},"id":4}
← {"jsonrpc":"2.0","result":{"screen":"...","cursor":{"row":2,"col":1},"size":{"cols":100,"rows":30}},"id":4}

// Terminate the session and close the endpoint
→ {"jsonrpc":"2.0","method":"pty/kill","params":{},"id":5}
← {"jsonrpc":"2.0","result":{},"id":5}

Command-and-platform notes

command / --cmd specifies the hosted command; the caller is responsible for passing a command that is available on the current platform:

PlatformRecommended commandNotes
Linux / macOSbashzsh, sh, node -i, etc. are also fine
Windowspowershell.exe / cmd.exethe .exe suffix is required

On Windows, node-pty (ConPTY) does not do PATH lookup for bare command names: passing names without .exe, such as powershell or bash, fails with File not found. Pass the executable name with its suffix, or a full path (e.g. C:\Program Files\Git\bin\bash.exe).

Next steps

  • See the Protocol and API Reference for the full messages and error codes of pty/read, pty/write, pty/wait, pty/status, pty/resize, and pty/kill.
  • Integrate terminal capability into an MCP host; see MCP Adapter.

MIT / ISC License