Universal CLI Session Broker for AI Agents — Playwright for CLIs
Shellwright is a cross-platform, PTY-backed session broker that transforms terminal interaction into a clean, machine-readable protocol for AI agents. Any agent that can shell out commands can use Shellwright to drive interactive CLIs.
AI coding agents hit a wall the moment a CLI asks a question. npm init wants a project name. terraform apply wants confirmation. ssh wants a password. git rebase -i opens an editor. The agent's shell tool can't type into these prompts — it hangs, times out, or crashes.
Today's workarounds are fragile: per-tool --yes flags that don't cover all cases, MCP servers locked to specific agent frameworks, or ecosystem-specific PTY support (Codex CLI for OpenAI only, Gemini CLI for Google only).
Shellwright fills the gap: one CLI tool, any agent, any platform, any interactive program.
# Install globally
npm install -g shellwright
# Or run directly without installing
npx shellwright start --name build -- npm run buildPlatform-specific binaries (Windows, macOS, Linux) are bundled automatically.
cargo install shellwrightgit clone https://github.com/nielsbosma/shellwright
cd shellwright
cargo build --releasesequenceDiagram
participant Agent as AI Agent
participant SW as shellwright
participant App as Interactive CLI
Agent->>SW: start --name deploy -- terraform apply
SW-->>Agent: {"state": "spawning", "pid": 1234}
Agent->>SW: wait deploy --for "Enter a value"
SW->>App: (PTY output streams)
App-->>SW: "Do you want to perform these actions? Enter a value:"
SW-->>Agent: {"matched": true}
Agent->>SW: send deploy "yes"
SW->>App: yes⏎
SW-->>Agent: {"message": "Input sent"}
Agent->>SW: wait deploy --for "Apply complete"
App-->>SW: "Apply complete! Resources: 3 added"
SW-->>Agent: {"matched": true, "match_text": "Apply complete"}
Agent->>SW: read deploy --tail 5
SW-->>Agent: {"text": "Apply complete! Resources: 3 added..."}
Agent->>SW: terminate deploy
SW-->>Agent: {"message": "Session terminated"}
shellwright start --name build -- npm run build # Start session
shellwright read build # Read output
shellwright read build --tail 10 # Last 10 lines
shellwright read build --since 42 # Since cursor 42
shellwright send build "y" # Send input + Enter
shellwright send build "y" --wait-for "done" # Send + wait
shellwright wait build --for "PASS|FAIL" --timeout 30
shellwright status build # State + prompt info
shellwright list # All sessions
shellwright interrupt build # Ctrl+C
shellwright terminate build # KillEvery command outputs JSON by default, making it trivially parseable by agents:
{
"id": "a1b2c3",
"success": true,
"data": {
"session": "build",
"state": "exited",
"exit_code": 0,
"output_file": "/tmp/shellwright/sessions/build/output.txt",
"output_tail": "Build completed successfully",
"lines": 847
}
}Use --no-json for human-readable plain text output.
- Agent-agnostic: Works with any agent that can run shell commands
- Cross-platform: First-class Windows ConPTY + Unix PTY support
- Daemon-backed sessions: Persist across agent crashes and context resets
- Token-efficient output: Filesystem-first (file paths + tail), cursor-based reads
- Prompt detection: Heuristic + pattern matching with confidence scores
- Wait-for patterns:
shellwright wait build --for "PASS|FAIL"— thewaitForSelectorof CLIs - Security: Dangerous command detection, secret redaction
- Clean output: VT terminal emulation strips ANSI noise, collapses progress bars
MIT