parkerhancock/dev-terminal
Persistent terminal (PTY) session management via HTTP API for AI assistants
0 stars0 forksUpdated Jan 7, 2026
npx skills add parkerhancock/dev-terminalREADME
Terminal automation for AI assistants. Inspired by dev-browser.
Key features:
- Persistent sessions - Create once, interact across multiple scripts
- SSH support - Connect to remote servers with the same API
- Headed mode - Browser UI to watch AI actions in real-time
- Full PTY support - Run interactive TUI apps (htop, vim, ncurses, etc.)
- LLM-friendly snapshots - Text, ANSI, or SVG output for AI analysis
Installation
Claude Code Plugin
/install parkerhancock/dev-terminal
Restart Claude Code after installation.
Manual / Standalone
Requires Node.js v18+.
git clone https://github.com/parkerhancock/dev-terminal
cd dev-terminal && npm install
Quick Start
Start the server:
./server.sh # Headless
./server.sh --headed # With browser UI
Create and interact with terminals:
import { connect, sleep } from "./src/client.js";
const client = await connect();
const term = await client.terminal("my-app");
await term.writeLine("ls -la");
await term.waitForText("total");
const snap = await term.snapshot();
console.log(snap.text);
await term.key("ctrl+c");
client.disconnect();
Client API
Connection
import { connect } from "./src/client.js";
const client = await connect(); // Default: http://localhost:9333
const client = await connect("http://..."); // Custom server URL
Client Methods
// Create or reconnect to a named terminal
const term = await client.terminal("name");
const term = await client.terminal("name", options);
// List all terminal names
const names = await client.list();
// Close/kill a terminal
await client.close("name");
// Get server info
const info = await client.info();
// Disconnect (terminals keep running)
client.disconnect();
Terminal Options
const term = await client.terminal("name", {
// Local terminal options
command: "bash", // Shell or command to run
args: ["-l"], // Arguments (default: login shell)
cols: 120, // Width in columns (default: 120)
rows: 40, // Height in rows (default: 40)
cwd: "/path/to/dir", // Working directory
env: { MY_VAR: "value" }, // Additional environment variables
// SSH options (for remote terminals)
ssh: {
host: "example.com", // Required
username: "deploy", // Required
port: 22, // Default: 22
password: "...", // Password auth
privateKey: "...", // Key content (not path)
passphrase: "...", // For encrypted keys
agent: process.env.SSH_AUTH_SOCK, // SSH agent
},
});
Terminal Methods
// Write raw data
await term.write("hello");
// Send a line (adds Enter)
await term.writeLine("ls -la");
// Send special keys
await term.key("enter");
await term.key("ctrl+c");
await term.key("up");
// Get screen snapshot
const snap = await term.snapshot();
console.log(snap.text); // Plain text (ANSI stripped)
console.log(snap.raw); // Raw output with ANSI codes
console.log(snap.lines); // Array of lines
console.log(snap.alive); // Process still running?
console.log(snap.exitCode); // Exit code if exited
// Get SVG rendering
const snap = await term.snapshot({ format: "svg" });
console.log(snap.svg);
// Resize terminal
await term.resize(80, 24);
// Clear output buffer
await term.clear();
// Wait for text to appear
const found = await term.waitForText("Ready", { timeout: 5000 });
// Wait for process to exit
const code = await term.waitForExit({ timeout: 10000 });
Special Keys
| Category | Keys |
|---|---|
| Arrows | up, down, left, right |
| Control | enter, tab, escape, backspace, delete |
| Ctrl+X | ctrl+c, ctrl+d, ctrl+z, ctrl+l, ctrl+a, ctrl+e, ctrl+k, ctrl+u, ctrl+w, ctrl+r |
| Function | f1 - f12 |
| Navigation | home, end, pageup, pagedown, insert |
SSH Remote Terminals
Connect to remote servers via SSH. The API is identical to local terminals.
import * as fs from "fs";
import * as os from "os";
import * as path from "path";
// Private key authentication
const term = await client.terminal("server1", {
ssh: {
host: "192.168.1.100",
username: "deploy",
privateKey: fs.readFileSync(path.join(os.homedir(), ".ssh/id_rsa"), "utf8"),
},
});
// Password authentication
con
...
Publisher
Statistics
Stars0
Forks0
Open Issues0
LicenseMIT License
CreatedJan 6, 2026