Start
Using llx
The everyday reference: the command line, a session's keys and slash commands, sign-in and models, and how sessions are kept. For the short version see the README.
- Command line
- In a session
- Signing in and choosing a model
- Sessions and the daemon
- Project instructions
Command line
llx opens a session at the terminal, and llx exec (or -p) runs one task and exits. llx decide asks one question about stdin and prints the option the decision model picked.
llx # a session at the terminal
llx "fix the failing test in src/parse.rs" # a session that starts with this task
llx -c # go on with the newest session here
llx exec "fix the failing test in src/parse.rs" # one task, then exit (also: llx e, llx -p)
llx exec -y "run the tests and fix what fails" # allow commands and edits without asking
llx --mode plan "how should we split src/parse.rs?" # read-only: change no file
git diff | llx -p "review this change" # piped stdin is added to the prompt
llx exec - < task.md # the prompt from stdin
llx exec -y "fix the lint" </dev/null # from a script whose stdin stays open
llx exec -C ../site "open http://localhost:3000 and check that sign-up works"
llx exec --json -y "update the changelog" | jq -c 'select(.type == "tool.call")'
llx exec --schema '{"type":"object","properties":{"version":{"type":"string"}},"required":["version"]}' \
"which version is this crate?" # the data alone on stdout
llx exec resume --last now update the README # one more task in the newest session
git diff | llx decide "Does this break the public API?" # yes or no, in about a secondWith exec, given a PROMPT, stdin that is not a terminal is read to its end and added to the
prompt, and llx says so on stderr. A caller whose stdin stays open (a harness with a pipe, ssh
without -n, a while read loop) should pass </dev/null.
Options
| Option | Meaning |
|---|---|
-C, --cd DIR |
The workspace: paths resolve in it and files change only inside it. Default: the current directory. |
--mode MODE |
A named set of rules: default, plan, bypass, or your own from settings.json (see Modes and approvals). Also --permission-mode. Default: default. |
--allow RULE, --deny RULE |
Add a rule to the mode's for this run: bash(cargo test *), edit(docs/**), browser (the syntax). Repeat them. A deny refuses in every mode, -y included. |
-y, --yes |
--mode bypass: allow commands, file changes and browser actions without asking. Also --yolo and --dangerously-skip-permissions. Giving it with --mode is a usage error. |
-p, --print |
Run the prompt as one task and exit, as exec does. |
-c, --continue |
Go on with the newest session of this directory, as resume --last does. |
--json |
With exec or -p: one JSON event per line on stdout (see --json). |
--schema SCHEMA |
With exec or -p: end with data matching this JSON Schema (inline, or @file), printed alone on stdout. |
-o, --output-last-message FILE |
With exec or -p: also write the final answer, or the data with --schema, to FILE. With --schema and no data that matched, the file is left empty. |
-v, --verbose |
Show each tool result and model turn in the trace. With --json, the trace also goes to stderr. |
--provider PROVIDER |
Where the agent's chat model comes from: a provider of the model catalog by id: openai (a ChatGPT sign-in or a key), openrouter, anthropic, deepseek, xai… Env LLX_PROVIDER. Default: the one /login saved, else the one signed in to. |
-m, --model MODEL |
The agent's chat model, a model id of the provider's (any OpenRouter id works). Env LLX_MODEL. Default: the one /login saved, else gpt-6-luna on OpenAI and anthropic/claude-haiku-5.5 on OpenRouter. |
--reasoning LEVEL |
How much the chat model reasons: off, minimal, low, medium, high, xhigh, max or ultra, as far as the model takes it (a level it does not take is a usage error; /login lists its levels). Env LLX_REASONING. Default: the one /login saved for that model, else the model's own. |
--decision-model MODEL |
The browser's decision model. Env LLX_DECISION_MODEL, default ~typesafe/jev-latest. |
--max-turns N |
Model turns for one task (50; 1 to 10000). |
--max-steps N |
Actions for one browser task of the decision model (40; 1 to 10000). |
--timeout SECONDS |
Seconds one task may take (1800; at most 86400). It stops at the first model turn past them, or while the task waits on its monitors or agents. Time spent waiting on you (an approval, a question) does not count. |
--no-daemon |
Run the session in this process instead of the daemon (llx serve). Env LLX_NO_DAEMON=1. exec always runs in process. |
--show-browser |
Show the browser window, and a window for each terminal session bash keeps. By default they show in a session, and stay hidden in exec and over SSH (SSH_CONNECTION or SSH_TTY set; the browser then works without a window). The browser window opens only when the browser is first used. A shown window is an ordinary one: it comes to the front when it opens, without taking the keyboard, and goes behind other windows like any other. |
Commands
logout: forget every saved sign-in: the ChatGPT tokens and the OpenRouter key. (Signing in is/loginin a session.)sessions: list the saved sessions, newest first, with the directory each ran in.exec [PROMPT | -](aliase): run one task without a session and exit, with the answer alone on stdout.exec resume [ID | --last] [PROMPT]runs one more task in a saved session. In CI, the GitHub Action runs it.decide QUESTION: ask the decision model one question about stdin (--choices a,b,…instead of yes or no,--expect CHOICEto exit 1 on any other,--jsonfor the probabilities and the cost) and print the option it picked. No agent, no tools; it needs an OpenRouter key. The reference has its options and exit codes.resume [ID | --last] [PROMPT]: go on with a session at the terminal.--lastis the newest session that ran in this workspace (else the newest of all, with a note).doctor: check that everything a run needs is in place.mcp: servewindowto another agent over MCP on stdio (unix; see From another agent).serve: the daemon the sessions run in (unix).serve statussays whether it runs (its pid, its build, the terminals attached, the sessions open and working, those moved to the background, the jobs; exit 1 when none runs),serve stopends it, stopping every session's task first.
In a session
A session needs a terminal on stdin that its interface can draw on; without one (or where the
interface cannot start) it is a usage error pointing to llx exec, which prints the same blocks
(each call, the answer, how it ended) without the live part.
The screen
- What finished goes into the terminal's own scrollback, so scrolling, selecting and copying are the terminal's. Only the bottom is redrawn: the call running,
Working (12s · esc to interrupt), the messages you queued meanwhile, and the prompt❯. - Under the prompt, a list shows the session, the agents it started (as a branch) and the jobs running; with no agents it is gone. Time and tokens follow each row's status. The other sessions take one line,
← 2 other sessions (1 working, 1 waiting for you). - ↓ from an empty prompt gives the list the keys: ↑↓ choose, Enter or → shows an agent's transcript,
xstops an agent or a job, Esc or ← go back. - Each session gets a short title from its first task, made in the background by the same model at its lowest reasoning level (the task never waits for it), shown in the list and saved with the session.
- A successful
editshows an inline diff with old and new line numbers, context, and red and green bands that fill the row, also in the scrollback. Long lines wrap; large previews are bounded and marked when cut. - Markdown answers support tables with aligned columns, wrapped cells and inline styles. On very narrow terminals, cells are shown vertically.
- Consecutive successful calls of the same tool are joined with
↳; failures and questions stay distinct.
Typing
- Enter sends. Shift+Enter, Ctrl-J or a line ending in
\start a new line; a paste keeps its lines. Up and Down walk earlier entries. - While a task works, Enter sends what you type to it, read at its next step (
↳); Tab keeps it for after the task (⏎). - Ctrl-R finds the last earlier entry with the words already typed (type them first; again for older ones). Ctrl-G writes the entry in
$EDITOR. - Clipboard text shows as
[Paste](numbered for several) and is expanded when sent. - Shift+Tab goes round the modes (default → plan → bypass → your own → default) without Enter; while a task runs, the switch waits until it ends.
Attaching files
- Drag a file into the terminal or paste its path: a picture (PNG, JPEG, GIF, WebP, up to 8 MB) becomes
[image: shot.png], sent to the model as one from a copy kept in~/.llx/pasted; anything else becomes[file: notes.md], sent as its path for the agent to read. Several at once work. @followed by a few letters lists the workspace's files; Enter or Tab puts the chosen path in.- Ctrl+V attaches the clipboard's picture (macOS).
-i FILE(--image) attaches pictures to the first task, in a session or inexec; a file that is missing or not a picture is a usage error before any model is called.
Slash commands
Typing / lists them. Tab completes the selected command (with a trailing space for /mode and /permissions); Enter runs exactly what is typed.
| Command | What it does |
|---|---|
/login |
Signs in, and chooses the provider, the model and its reasoning level (see below). |
/model |
Chooses the model and its reasoning level. |
/mode [name] (also /permissions) |
Lists the modes or switches to one. |
/new (also /clear) |
Opens a new session and shows it, even while a task works; the old one goes on in the background. |
/status |
The models, the workspace, the mode, the session and any terminal session still running. |
/rewind (also /undo, or Esc Esc on an empty prompt) |
Goes back to before one of the conversation's tasks: the files edit changed (the agents' too; not what commands changed), the conversation (the task's words back in the prompt; the session's agents are let go), or both. |
/diff |
The changes since the last commit, new files too. |
/init |
Writes an AGENTS.md for the project. |
/copy |
Copies the last answer that says something. |
/usage (also /cost) |
What the session spent. The footer's right end says it all along (24.1k in · 87% cached · 1.2k out · $0.042), a resumed session's earlier tasks included. |
/help, /exit (also /quit, or Ctrl-D) |
Help; leave. |
Several sessions
- Each session is recorded in its own file, and Ctrl-C stops only the one shown.
- ← on an empty prompt lists the sessions in this project: those open (working, then waiting for you, then idle or done), "+ New session", then this directory's saved sessions, newest first. ↑↓ choose, Enter or → opens one (a saved one is resumed in a session of its own),
xstops a session's task without switching to it, Esc or ← close the list. - At most 8 are open: another closes the oldest idle one.
- An approval or a question from a session not shown names it (
session <name> (in the background)), ignores keys for 300 ms and is answered as any other; its own choices wait until it is shown. - When a session not shown finishes, the one shown says
● Session "…" finished · ← to open.
Signing in and choosing a model
/login asks for a provider (every one of the catalog in one list: the popular first, then the current one and those signed in to, then the rest by name; ✓ marks those signed in to or with a key set; type to search by name or id), signs you in to it, then opens its model list (↑↓ choose the model, ←/→ change its reasoning level, Enter confirms).
- OpenAI, with a ChatGPT sign-in: your browser opens OpenAI's sign-in page and comes back to llx on
127.0.0.1:1455(or 1457), and llx goes on by itself, with nothing to paste; requests are billed to your ChatGPT plan, and/loginand/modeloffer the models the ChatGPT backend serves, those it serves alone (the Codex and Pro models) too. On a machine without a browser, open the address shown elsewhere and paste the address the browser ends on. - OpenRouter, with a key: paste it (it is not shown), or sign in in the browser for a new one.
OPENROUTER_API_KEYworks too, and wins over a saved key. - Any provider of the model catalog (Anthropic, Google, xAI, DeepSeek, Mistral, Groq, Moonshot, Z.ai, Together, Fireworks… about 200), with a key: paste it, or set the variable models.dev names for it (
ANTHROPIC_API_KEY,DEEPSEEK_API_KEY…), which wins over a saved key. OpenAI takes an API key too. Each is called over OpenAI's chat completions at the address the catalog gives.
The models, their context windows, reasoning levels and defaults come from one catalog, models.dev's (MODELS.md): its files for the popular providers are built in, and a session fetches its newest data in the background, at most once a day, for the next one. Each request's cost comes from the catalog's prices when the provider reports none (a ChatGPT plan's as its API-equivalent value).
/model chooses among the models of every provider signed in to. ←/→ change the highlighted model's reasoning level inline, and Enter confirms both. The current model keeps its level, and other models start at their own defaults. A list longer than 12 is searched by typing (Backspace edits the query, Esc clears it, then cancels) and scrolls with ↑↓, PageUp, PageDown, Home and End. Shift+Up and Shift+Down move the level without a menu.
The choice is put in at once, in the same conversation, and saved as the default for later sessions and for exec. The browser's decision model runs on OpenRouter, so goals on window tabs need an OpenRouter key whichever provider the agent thinks with.
Sessions and the daemon
Every run is saved as a session in ~/.llx/sessions/<id>.json; set LLX_SESSIONS to keep them elsewhere. A session records each task and how it ended, but not the conversation itself. resume therefore starts a new conversation that is told the earlier tasks, the directory they ran in, and where the browser was; at the terminal, the earlier tasks and their answers are drawn first (the last 20). In a session, each task continues the same conversation.
A session at the terminal runs in a daemon, llx serve:
- One per config directory, found at a socket in
$TMPDIR/llx-<uid>/(a directory only you may enter), started by the firstllx(detached, in a session of its own, its errors indaemon.logbeside the sign-ins) and attached to by every later one. - It holds the sessions with their agents, jobs and terminal sessions, the models, and the one window;
llxdraws, reads the keys and speaks to it over the socket. - Each terminal's sessions work in its directory, with its environment, and with the options its command line gave. Each terminal has its own questions, and quitting one names only its own work.
- A session is open at one terminal at a time: resuming one open at another says so.
- Closing a terminal stops its sessions' work; the daemon lives on until
llx serve stop. Closing the window there stops nothing: the tasks working in it are told, and it opens again when next used. - A plain
llxin a directory where sessions were moved to the background comes back to them;llxwith a task,resumeor any option opens new sessions beside them, which wait for the next plainllx. - A daemon of another build is stopped and replaced only when nothing needs it (no terminal attached, no session open or moved to the background, no task, monitor or schedule); otherwise the session runs in this process, and llx says so, as it does when the daemon cannot be reached.
--no-daemon(orLLX_NO_DAEMON=1) always runs in process, and so doesexec.
The design is in daemon.md.
Project instructions
llx reads instruction files, so a repository that already has them works as it is:
- your own, for every project:
~/.llx/AGENTS.md; - the project's: in each directory from the git repository's root down to the workspace, the first of
AGENTS.override.md,AGENTS.mdandCLAUDE.md, root first, so a deeper file wins over a shallower one; - a directory below the workspace: its file comes with the result of the first
readoreditof a file there, and covers that directory's tree.
A line that is only @path brings that file in (relative to the file, or ~/…), three levels deep, each file once, as in CLAUDE.md. The task you give wins over every file. Each file is capped at 16 KiB and those read at the start at 32 KiB together, with a note when something was cut. They reach the agent in a context block with the environment: the workspace, the OS, the date, the mode, and whether a browser is available.
The prompt cache
The context is built so the prompt cache keeps working. It is a message of its own after the system prompt, the same for every task and session in a workspace on a day (the date has no time), and it is marked for the cache, so a new session reads it from there. Files are read once per session; a subdirectory's file is appended with a call's result; a mode change is a note appended later; old page states and screenshots are dropped together once past a budget, not one at a time. Nothing earlier in the conversation is rewritten turn by turn.