xx

minimal unix coding harness

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

xx (pronounced "kiss kiss") is a unix-flavored coding harness. it starts instantly, runs in a container, ships as a single binary, hides thinking and tool output, and extends via programs instead of plugins. it barely has any features and that's the way we like it.

features

small & fast

xx ships on mac and linux as a single <800K binary that starts instantly - perfect for pipelines or quickly launching sessions:

~/dev> xx resolve these conflicts
~/dev> xx /review
~/dev> rev diff | xx -p "write the commit message" | rev title -
~/dev> xx -p "what changed this week?" > notes.md
~/dev> xx --json "how many TODOs are in src/?"
~/dev> until make test; do xx -p "fix the failing tests"; done

like other harnesses, -p runs and exits, printing agent output to stdout while tool calls go to stderr. --json is like -p but streams agent actions as json to stdout, tool calls to stderr.

xx only has five tools:

sandboxed

i once had an agent get confused and run rm -rf ~, so... yeah. xx runs every bash call in a long-lived linux container (via container on apple and podman on linux) which can only access specific paths on your host machine. by default it's ~/dev and ~/.rev, but you can change them or add more.

think of it as a safety net, not a security system: the goal is to prevent agents from accidentally running shell commands that impact your host system, not protection against rogue or malicious models.

you can run commands in the container from your host by using xx -x:

~/dev> xx -x echo hi world!
hi world!
~/dev> xx -x cove build -o container-bin
~built container-bin (5.47s)
# forward `env` vars using `-e`
~/dev> xx -x -e ELEVENLABS_API_KEY ./container-bin
Running in the container!
# explore the container using a shell
~/dev> xx -x sh
/Users/chris/dev/container-bin #

to run xx directly on your host computer, pass --jailbreak at startup. the prompt turns red so you don't forget:

~/dev> xx --jailbreak
◇

to see information about the container, run /container:

◆ /container
backend apple container
name xx
image alpine:latest
state running
mounts ~/dev, ~/.rev
workdir ~/dev/my-project
memory 163840 MiB
cpus 20

hooks

hooks are executables in a directory ~/.config/xx/hooks/<event>/ or files named ~/.config/xx/hooks/<event> that run on the host in response to an agent event. write them in whatever language you want and update them without restarting xx. session info is passed to a hook via XX_ env variables.

for example, turn the tmux window yellow while the agent works:

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

available hooks:

session state:

commands

slash commands either send markdown directly to the model or run a program and put its output in the scrollback, skipping the model. they live in ~/.config/xx/commands/ and can be edited without restarting xx:

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

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

fork, set +x, is a program command. it runs on the host with the arguments you pass to the slash command and the XX_ env vars listed above in the hooks section. the output of fork goes directly into the scrollback, not the model.

to see all available slash commands, including the builtin ones, run /help:

◆ /help
/help this list
/status session overview
/clear forget this conversation and clear the screen
/cost how much this session has cost you
/context context window status
/compact replace history with a short summary
/compact <focus> guide the summary
/model info on the current model
/container info on the container
/docs the docs the agent can fetch
/docs <name> make the agent read a doc
/transcript everything sent over the wire to the model
/quit exit xx
commands in ~/.config/xx/commands:
/config
/fork
/implement
/review

$ shell commands

run a shell command in the container directly by typing $ on an empty line, then your command. typing $$ on an empty line locks you in "shell mode" where the input assumes shell commands until you ESC, ctrl-c, or backspace on an empty line. $ cd <path> will move xx's current working directory.

the shell commands you run and their output gets sent to the model with your next message:

$ pwd
~/dev/example
$ ls src
main.cv
$ cd src
~/dev/example/src
$ cat main.cv
print("hello, world!")
$ ~/dev/example/src

xx.conf

override default settings with ~/.config/xx/xx.conf:

# claude* → anthropic, vendor/model → openrouter, anything else → openai
model claude-fable-5-1

# low | medium | high | max
effort high

# drop sessions idle longer than this (min, h, d, wk). 0 keeps forever
keep_sessions 30d

container {
  # you can switch between multiple containers
  # by using different names
  name xx

  # false runs tools on the host, like --jailbreak
  enabled true

  # use any image you want
  image alpine:latest

  # memory in MiB. 0 leaves it to the backend
  memory 8192
  cpus 0

  # host directories available in the container
  mounts ~/dev ~/.rev

  # install packages beyond the default set
  package jq
  package fd apk add --no-cache fd
  package honest curl -fsSL https://because.sh/honest | sh
}

you can also start xx with --model or --effort to override settings for a single session.

docs

docs are markdown files in ~/.config/xx/docs/ or .xx/docs/ explaining concepts. when xx starts, or when it runs the "docs" tool, it sees a list of available docs. running one enlightens it.

you can force xx to read a doc by sending /docs <name> or find out what's available with the /docs command.

besides the docs feature, xx (like all harnesses) sends ~/.config/xx/AGENTS.md and AGENTS.md (if they exist) with every request.

sessions

xx automatically tracks every transcript as an append-only jsonl file in ~/.config/xx/sessions. keyed by the current directory, they're deleted (by default) after 30 days.

you can continue the most recent session for the current directory or any session using -c. list them with -s:

~/dev> xx -c continue the last session
~/dev> xx -c 3 continue a specific session
~/dev> xx -s list them

provider-agnostic

xx works with anthropic, openai, or any anthropic/openai-compatible providers like openrouter. big whoop.

model format and env vars:

you can also point ANTHROPIC_BASE_URL, OPENAI_BASE_URL or OPENROUTER_BASE_URL at a proxy or local server

~/dev> OPENAI_BASE_URL=http://localhost:11434/v1 xx --model llama3.2

the /cost command hits the models.dev API to give you accurate pricing information for your model.

...and more

get it

xx ships as a single binary for mac and linux:

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