One session model
A single IPTYSession + PTYSessionManager. Local PTYs, CLI-over-IPC, and remote peer sessions all look identical to your UI layer.
One session model. Pluggable transports. Factor out the plumbing every terminal UI rebuilds — and ship local PTY, IPC, and Tailscale mesh when you need them.
pnpm add @vibecook/avocado-sdk
Every terminal UI project ends up reinventing PTY spawning, output buffers, resize coordination, focus handoff, and multi-device sync. Avocado owns that layer.
A single IPTYSession + PTYSessionManager. Local PTYs, CLI-over-IPC, and remote peer sessions all look identical to your UI layer.
Ship only what you need — node-pty for local shells, UDS/Named Pipe for CLI bridges, Tailscale mesh via @vibecook/truffle for cross-device sharing.
Drop-in React components and hooks. Default xterm.js engine, optional restty (libghostty-vt + WebGPU/WebGL2) via engine="restty".
Strict TypeScript, source maps, and a small public surface — IPTYTransport, IPTYSession, ITerminalStoreSync. Optional peers only for the subpaths you import.
The SDK is carved into focused modules. Core stays free of heavy peers; transports and React opt in only when you need them.
IPTYTransport. The session manager routes by session source — local, IPC, and remote peers feel identical above that boundary.Three layers, one mental model. Understand these and the rest of the API falls into place.
A running PTY with id, dimensions, output stream, and lifecycle events — output, resized, exit, focusChanged. Every backend (local, IPC, proxy) implements the same interface.
The manager owns sessions and registered transports. Each session has a source — 'local', 'ipc', or 'ws'. Transports implement a symmetric viewer/owner contract: input, resize, kill, focus, subscribe — plus owner-side output and lifecycle.
Tracks virtual terminals (UI surfaces attached to a session) and enforces one-active-terminal-per-session. Multiple passive viewers can share a shell; only one accepts input. Powers multi-window and multi-tab layouts.
Install the SDK for embedding, the CLI for shell wrapping — and only the peer deps for the subpaths you import.
The library. Session manager, transports, and React surface via subpath exports.
CLI binary avo — wrap any command and sync to a host over IPC.
| Subpath | Required peer(s) |
|---|---|
@vibecook/avocado-sdk |
None — core session manager + types only |
…/node-pty |
node-pty |
…/transport-ipc |
None — built-in Node networking |
…/transport-truffle |
@vibecook/truffle ^0.6 |
…/react |
react, xterm, @xterm/addon-fit · optional restty for Ghostty VT |
# Server-side app using local PTY + mesh sync
pnpm add @vibecook/avocado-sdk node-pty @vibecook/truffle
Runtimes: Node.js ≥ 18 · modern browsers (React subpath) · Electron (playground is Electron).
Spawn a session on the host, expose a backend, render with the grid. Mesh is one more block of wiring.
Electron main or Node process: create the session manager, spawn a local PTY, register it.
import { createPTYSessionManager, createTerminalService, } from '@vibecook/avocado-sdk'; import { LocalPTYSession } from '@vibecook/avocado-sdk/node-pty'; import { spawn as ptySpawn } from 'node-pty'; const sessionManager = createPTYSessionManager(); const terminalService = createTerminalService(sessionManager); const session = LocalPTYSession.spawn( (opts) => ptySpawn(opts.command, opts.args, opts), { command: process.env.SHELL ?? '/bin/bash', args: [], cwd: process.cwd(), cols: 120, rows: 32, }, { command: 'bash', cwd: process.cwd() } ); sessionManager.registerSession(session);
Wrap your tree with AvocadoProvider and drop in a terminal surface — behavior from the SDK, every pixel of chrome yours.
import { AvocadoProvider, TerminalSurface } from '@vibecook/avocado-sdk/react'; export function App() { return ( <AvocadoProvider backend={electronBackend}> <TerminalSurface sessionId={sid} terminalId={tid} engine="restty" isActive /> </AvocadoProvider> ); }
Add the truffle transport and the same session appears on every peer.
import { createMeshNode } from '@vibecook/truffle'; import { PTYMeshBridge, PTYSyncStore, RemoteSessionService, } from '@vibecook/avocado-sdk/transport-truffle'; const node = await createMeshNode({ appId: 'my-app', deviceName: 'laptop', }); const bridge = new PTYMeshBridge({ node, sessionManager }); const syncStore = new PTYSyncStore({ node }); const service = new RemoteSessionService({ node, sessionManager, bridge, syncStore, }); await bridge.initialize(); await service.enable();
Same session manager, different wires. Compose freely — local + IPC + mesh is a common Electron layout.
Spawn shells in-process with LocalPTYSession. Ideal for Electron main and Node servers.
Unix Domain Socket (macOS/Linux) or Named Pipe (Windows). Bridge avo CLI sessions into a long-running host.
Cross-device session sync over Tailscale. Peer-first routing, SyncedStore discovery, focus handoff.
import { createUDSServer, createPTYIPCBridge, } from '@vibecook/avocado-sdk/transport-ipc'; const udsServer = createUDSServer(); udsServer.start({ socketPath: '/tmp/my-app.sock' }); const bridge = createPTYIPCBridge(sessionManager); bridge.initialize(udsServer);
# Wrap your shell / any command avo avo claude avo -- htop avo -s /tmp/my-app.sock bash # Standalone: buffers until host connects avo --no-sync bash
Provider wiring, grid layout, active-terminal switching, and two renderers — ready for production UIs.
| Export | Role |
|---|---|
AvocadoProvider |
Root context — pass a TerminalBackend (Electron IPC, WebSocket, …) |
TerminalSurface |
Headless terminal surface — behavior only, styled via [data-active]/[data-engine] attributes |
useTerminalGrid / useResizeHandle |
Headless grid state (pluggable layout) and drag-to-resize prop getters |
engine: 'xterm' |
Default TerminalView engine (xterm.js + FitAddon) |
engine: 'restty' |
Optional Ghostty VT path via restty peer (WASM + WebGPU/WebGL2) |
usePTYSessions, useTerminals, useTerminalSnapshot, … |
Live session & terminal state hooks |
Full signatures and types → API reference · React
| Path | What it is |
|---|---|
packages/sdk/ |
Source for @vibecook/avocado-sdk |
packages/cli/ |
Source for @vibecook/avocado (avo) |
apps/playground/ |
Electron showcase — local + IPC + mesh in one app |
docs/ |
This site — static HTML on GitHub Pages |
pnpm install
pnpm run typecheck
pnpm run build
pnpm run playground # Electron demo
Open the API reference, clone the playground, or drop the SDK into your next Electron or Node app.