Readme
Scriptty - Terminal Proxy Demo Engine
Create realistic, reproducible terminal demos for any interactive CLI — without depending on how the application echoes input.
This project runs a command-line program inside a pseudo-terminal (PTY), decouples execution from presentation , and renders scripted interactions as human-like typing.
Perfect for:
README demos
CLI tutorials
Example demo for rcypher CLI
Why This Exists
Tools like expect , script , and even asciinema struggle with realistic demos because:
Input echo timing is controlled by the target application
Keystrokes often appear only after a newline
Readline-based apps redraw internally
Typing realism is unreliable and brittle
This tool solves that by design.
Instead of relying on the application to echo input, it introduces a proxy that controls what the viewer sees independently from what the program receives .
Installation
Prebuilt binaries (recommended)
Download from the stable release
Build from source
scriptty is written in Rust. You’ll need the Rust toolchain installed.
1. Install Rust
If you don’t have Rust yet, install it with:
curl -- proto ' =https' -- tlsv1 .2 - sSf https://sh.rustup.rs | sh
Then restart your shell or run:
source " $HOME/.cargo/env"
Verify installation: rustc -- version
2. Clone the repository
git clone https://github.com/justpresident/scriptty.git
cd scriptty
3. Build the project
cargo build -- release
The binary will be available at: target/ release/ scriptty
You can run it directly:
./target/release/scriptty -- help
Optional: install globally
If you want scriptty in your $PATH:
cargo install -- path .
Then you can run:
scriptty - - help
Requirements
Troubleshooting
If the build fails on Linux, make sure you have:
build-essential
pkg-config
On macOS, make sure Xcode Command Line Tools are installed:
xcode-select -- install
Core Idea
Decouple program execution from terminal presentation.
The program receives input instantly and deterministically.
The viewer sees carefully timed output that looks like real typing.
┌────────────┐
│ Program │ ( runs in PTY )
└─────▲──────┘
│
┌─────┴──────┐
│ Engine │ ( script + timing)
└─────▲──────┘
│
┌─────┴──────┐
│ Renderer │ ( what the viewer sees)
└────────────┘
Features
🧠 Program-independent typing simulation
🧪 Deterministic, scriptable demos
⌨️ Realistic per-character typing with jitter
⏱️ Controlled pauses and timing
📼 Compatible with asciinema recordings
🔁 Reproducible demos (great for CI)
🧩 Generic — works with any interactive CLI
How It Works
The target program runs inside a PTY
A script drives interaction deterministically
Input is sent immediately to the program
Output is intercepted and re-rendered
Typing is simulated visually, not echoed
This avoids:
line buffering
terminal echo quirks
readline redraw behavior
race conditions
Example Script
# Display narration to the viewer
show "=== Configuration Demo ==="
# Wait for bash prompt
expect "$ "
# Type a command with realistic delays
type "put github.username littlejohnny"
key Enter
# Wait for specific output before continuing
expect "saved"
show "Configuration saved! Now retrieving..."
# Small pause
wait 500ms
# Execute another command
type "get github.*"
key Enter
# Wait for the output
expect "littlejohnny"
Event Model
Internally, every script line maps to a command implementing the ScripttyCommand trait:
pub trait ScripttyCommand : 'static {
fn name ( & self ) -> & 'static str ;
fn parse ( args : & str ) -> Result < Self > where Self : Sized;
async fn execute( & self, ctx: & mut Context) -> Result < ( ) > ;
}
Program input and user-visible output are separate streams.
Script Commands
Command
Syntax
Description
wait
wait 1s or wait 500ms
Pause execution for specified duration
type
type " text here"
Simulate realistic typing (50-150ms per char), no implicit newline
send
send " text here"
Send bytes to program instantly (no typing simulation, no implicit newline)
key
key Enter , key Ctrl+ C , key Alt+ Left
Send a key press with optional modifiers (Ctrl+ , Alt+ , Shift+ )
show
show " message"
Display text directly to viewer (narration, comments)
expect
expect " pattern" or expect " pattern" 10s
Wait for pattern in output (default 5s timeout)
Project Status
🚧 Early stage / design-first
Planned next steps:
YAML / JSON script format
ANSI escape parsing (vt100)
Built-in asciinema exporter
Mistyped input simulation
Redaction and masking rules
Why Not Just Use Expect?
Because this tool solves a different problem.
Tool
Focus
expect
Automate interaction
asciinema
Record terminals
this project
Present interactions realistically
Inspiration
This project grew out of real-world frustration trying to record high-quality demos of readline-based CLI tools where input appeared instant, robotic, or incorrect.
License
Apache 2.0
Contributing
Ideas, feedback, and design discussions are welcome.
If you’ve tried to record CLI demos and hit similar limits — you’re exactly the audience.