Getting Started
Environment requirements
- Node.js >= 18 (see
enginesinpackage.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-10or newer). - Windows / macOS: prebuilt binaries are provided and work out of the box.
- Linux: no prebuilt binary; it is compiled from source at install time and requires
@xterm/headless(required): the screen-rendering backend, pure JS with no compile burden.
Installation
npm install @ai-zen/socket-ptyTo use it locally within the repo, build first and then consume via dist/:
npm install
npm run build
node dist/cli.js serve --cmd bash --socket /tmp/x.sockQuick examples
Start a service with the CLI
# 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 5174On successful startup it prints:
[socket-pty] 会话已启动,命令: bash
[socket-pty] 连接地址: 127.0.0.1:5174Common serve options: --cmd (required), --socket / --port (choose one, one is required), --cols / --rows (default 100 / 30), --cwd.
Start programmatically
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.sockConnect 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:
// 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:
| Platform | Recommended command | Notes |
|---|---|---|
| Linux / macOS | bash | zsh, sh, node -i, etc. are also fine |
| Windows | powershell.exe / cmd.exe | the .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, andpty/kill. - Integrate terminal capability into an MCP host; see MCP Adapter.