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, suppresses 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 <1MB 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/?"

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.

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.

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

~/dev> xx --jailbreak
◇

hooks

hooks are executables in ~/.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.

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

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 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 overview: model, session, context, cost, container
/clear forget the conversation and clear the screen
/cost tokens used this session and what they cost
/context how full the context window is
/compact summarize and drop the older part of the conversation now; /compact <focus> names what the summary must keep
/model the model, effort and thinking mode in use
/container the container the tools run in, if any
/docs the docs the agent can fetch; /docs <name> [request] sends one
/transcript what the model sees: the system prompt, tools and conversation, in $PAGER
/quit leave; the session is kept for xx -c
commands in ~/.config/xx/commands:
/config
/implement
/review

$ shell commands

run a shell command 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:

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

xx.conf

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

model claude-fable-5-1
effort high
keep_sessions 14d

container {
  mounts ~/dev ~/.rev ~/notes
  package jq
  package rg apk add --no-cache ripgrep
}

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.

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