Skip to Content

terminal

import { terminal } from "@tynd/core/client";

Real PTY sessions. ConPTY on Windows, POSIX PTY elsewhere. Pair with xterm.js  for a full interactive terminal UI.

spawn(opts?): Promise<TerminalHandle>

interface TerminalSpawnOptions { shell?: string; // default: $SHELL on Unix, %COMSPEC% on Windows args?: string[]; cwd?: string; env?: Record<string, string>; cols?: number; // default 80 rows?: number; // default 24 } const t = await terminal.spawn({ cols: 120, rows: 30 });

Option name is shell, not command.

TerminalHandle

interface TerminalHandle { id: number; write(data: string | Uint8Array): Promise<void>; resize(cols: number, rows: number): Promise<void>; kill(): Promise<void>; onData(handler: (chunk: Uint8Array) => void): () => void; onExit(handler: (code: number | null) => void): () => void; }

onData(handler)

Streams raw PTY bytes (base64-encoded on the IPC channel; decoded to Uint8Array for you).

t.onData((bytes) => xterm.write(bytes));

onExit(handler)

Fires once on child exit. code is null if killed by a signal (e.g. via kill()).

t.onExit((code) => console.log("shell exited:", code));

write(data)

await t.write("ls -la\n"); await t.write(new Uint8Array([0x03])); // Ctrl+C

resize(cols, rows)

Call after the user resizes the terminal UI.

kill()

Force-close the session. onExit fires with null.

list(): Promise<number[]>

IDs of currently-open sessions.

const ids = await terminal.list();

Example — xterm.js integration

import { Terminal } from "@xterm/xterm"; import { FitAddon } from "@xterm/addon-fit"; import { terminal } from "@tynd/core/client"; import "@xterm/xterm/css/xterm.css"; const xterm = new Terminal(); const fit = new FitAddon(); xterm.loadAddon(fit); xterm.open(document.getElementById("terminal")!); fit.fit(); const pty = await terminal.spawn({ cols: xterm.cols, rows: xterm.rows }); pty.onData((bytes) => xterm.write(bytes)); pty.onExit((code) => xterm.writeln(`\r\n[process exited: ${code ?? "killed"}]`)); xterm.onData((data) => pty.write(data)); new ResizeObserver(() => { fit.fit(); void pty.resize(xterm.cols, xterm.rows); }).observe(document.getElementById("terminal")!);

Notes

  • Output from the PTY is base64-encoded on the IPC channel.
  • Multiple concurrent sessions are supported — each gets its own thread and id.
  • Long-lived sessions survive across calls; handles live in a Mutex<HashMap<id, _>> inside os::terminal.
  • process — one-shot exec with buffered output.
  • sidecar — run a bundled binary as a PTY.
Last updated on