xx

minimal unix coding harness

curl -fsSL xx.sh | sh
xx extending itself via shell scripts without access to your file system

xx is a coding agent for the terminal. you type, it reads, runs, edits and writes, you watch. one binary, no runtime, no account: your own key and any model behind it. its tools run in a container, so it only touches the directories you give it. everything it knows is a plain file under ~/.config/xx, and extending it is writing one.

features

small & fast

one binary, about 600 KB, no runtime. starts before you let go of the enter key, so you reach for it the way you reach for grep.

~/dev> xx -p "resolve these conflicts"
~/dev> git diff | xx -p "write the commit message"
~/dev> xx -p "what changed this week" > notes.md

-p asks once and exits. the answer goes to stdout, tool calls to stderr, stdin is the prompt. pipe into it, pipe out of it, put it in cron. -e composes in $EDITOR.

sandboxed

every bash call runs in a long-lived linux container. apple container on macOS, podman on linux. only ~/dev and ~/.rev are mounted, at the same paths, so the agent can't reach the rest of the host. writes under ~/dev are real.

the container is made once and kept. a container block in xx.conf sets the image, memory, cpus, mounts and the packages that must be inside. add a package line and the next start installs it into the running container.

--jailbreak runs the tools on the host instead. the prompt turns red so you don't forget.

~/dev> xx --jailbreak
◇

unix flavored

everything it knows is a plain file under ~/.config/xx. config is xx.conf, key value per line, four keys: effort, thinking, model, container. misspell one and it won't start. --model and --effort override it for a session.

hooks and commands are files too, and chmod +x is the whole plugin api. stdin in, stdout out. built for tmux: /fork opens a new window, a hook can color the tab, $XX_TMUX is in the env.

hooks

executables in ~/.config/xx/hooks/<event>/, run on the host on start, busy, turn, idle, cd and shutdown, with the session in XX_ env vars. one line of sh turns the tmux window yellow while the agent works.

#!/bin/sh
tmux set -t "$XX_TMUX" window-status-style bg=yellow

commands

a slash command is a file in ~/.config/xx/commands/. drop one in and type its name. no restart.

~/dev> ls -l ~/.config/xx/commands
-rw-r--r-- review.md
-rwxr-xr-x fork

review.md is a prompt command. /review the diff sends the file, then the diff.

fork is a program command. it runs on the host with the arguments and XX_ env vars for the session, and what it prints goes to the scrollback, not the model. it's a tool for you. the one in the repo copies the session so far and opens it in a new tmux window.

$ runs shell commands

a $ on an empty line runs the command yourself, output on screen. $$ locks it. $ cd moves the session. what you ran, and what it printed, goes to the model with your next message under Commands I ran:.

$ rg -n TODO src/
◆ which of these can go

docs

~/.config/xx/docs/<name>.md, or .xx/docs/ in a project. the first line says when the doc is wanted and the agent fetches it then, instead of every prompt carrying every doc. /docs rev sends one yourself.

AGENTS.md holds standing instructions, user or project, nearest wins, re-read on every request.

sessions

always recorded, per cwd, as it happens. append-only jsonl. nothing to save.

~/dev> xx -c continue the last one
~/dev> xx -c 3 resume one
~/dev> xx -s list them

provider-agnostic

anthropic, or any openai-compatible provider like openrouter, with your own key. no account, no middle service, no telemetry.

auto-compaction

the window is 1M. at 800k it compacts itself. old tool output goes first, then the oldest turns, with a summary. /compact forces it. /context and /cost show where you stand.

it fills slowly to begin with. bash refuses cat, head, tail and sed -n and points the model at read, and tool output back to the model is capped at 60k chars.

get it

one binary for macOS and linux, arm64 and x86_64. set a key and go.

~/dev> curl -fsSL xx.sh | sh
~/dev> export ANTHROPIC_API_KEY=...
~/dev> xx
◆ ~/dev

source

about 4,300 lines of cove in 11 files. five tools: read, bash, edit, write, docs. ten slash commands. readable in an afternoon.