# pty-agent
An ultra-minimal observable PTY-backed coding agent in Rust using Rig.
```sh
OPENAI_API_KEY=... cargo run -- "fix the failing tests"
```
The process immediately starts a persistent PTY shell and streams that PTY
directly to stdout. The terminal you watch is the same terminal the Rig agent
observes and controls. The agent has exactly one tool, `terminal`, and all work
happens by typing into that PTY.
## Model
```text
user request -> Rig agent -> terminal tool -> shared PTY view -> memory/history -> continue
```
The shell launch order is `$SHELL`, then `/bin/bash`, then `/bin/sh`.
## Terminal Tool
The only tool is `terminal`.
Actions:
- `type`
- `enter`
- `type_and_enter`
- `ctrl_c`
- `key`
- `observe`
Observe modes:
- `screen`
- `recent_output`
- `command_history`
- `command_output`
- `memory_summary`
- `full_state`
## Terminal Mirror
There is no TUI framework, side panel, or hidden execution path. PTY output is
copied byte-for-byte to stdout as it arrives. Sparse status lines are written to
stderr with a `[pty-agent]` prefix so you can see when the agent is thinking,
typing, waiting, or finished without replacing the terminal view.
## Memory
The implementation keeps:
- a live VT-rendered screen model via `vt100`
- bounded raw and cleaned scrollback
- semantic command records with full output excerpts
- a rolling long-term text summary for older commands
This is intentionally small and hackable. It favors observability over
sandboxing: YOLO mode means no confirmations, no safety prompts, and no command
blocking.
## Docker
The Docker path uses `debian:bookworm-slim` and installs Rust plus native build
dependencies needed by the Rig/OpenAI stack. Debian publishes native ARM64 and
AMD64 images, so this works cleanly on Apple Silicon without emulation.
Run the agent inside a clean container-owned `/workspace` with no host project
mounted:
```sh
OPENAI_API_KEY=... /path/to/pty-agent/scripts/run-pty-agent-docker.sh "fix the failing tests"
```
By default the image runs:
```sh
cargo install pty-agent
```
Pin a crates.io version with:
```sh
PTY_AGENT_VERSION=0.1.0 ./scripts/run-pty-agent-docker.sh "fix the failing tests"
```
Before `pty-agent` is published to crates.io, test the same container using the
local checkout:
```sh
OPENAI_API_KEY=... ./scripts/run-pty-agent-docker.sh --local "fix the failing tests"
```
To launch the same container directly into a clean shell with `pty-agent`
installed from crates.io:
```sh
./scripts/shell-pty-agent-docker.sh
```
For a Rust-only shell without installing `pty-agent`:
```sh
./scripts/shell-pty-agent-docker.sh --no-install
```
Force a full rebuild after Dockerfile changes:
```sh
./scripts/shell-pty-agent-docker.sh --rebuild
./scripts/run-pty-agent-docker.sh --rebuild "fix the failing tests"
```
For local development only, mount this checkout at `/src/pty-agent`:
```sh
./scripts/shell-pty-agent-docker.sh --local
```