# Setup The first run on a terminal opens a full-screen wizard instead of the chat: the mark assembles, the name lights up, and it asks five questions one at a time, plus the three that are only sometimes there — the Claude Code login question where there is no API key and Claude Code is logged in, the Claude skills question on a machine that has some, and the herdr one on a machine that has [herdr](hooks.md#herdr). "First run" means the config file does not say `"setup": "done"` — the marker the wizard stamps when the last question is answered — rather than that no file exists, so a config written by hand, or by a build with fewer questions in it, still gets asked the ones it is missing. ``` codey setup step 1 of 5 ◆━━━━━━━━━━━━◇────────────◇────────────◇────────────◇ Which model should the agent use? ▌ ◆ Claude Opus 5 $5 / $25 per Mtok ◇ Claude Sonnet 5 $2 / $10 per Mtok ◇ Claude Haiku 4.5 $1 / $5 per Mtok ◇ custom… claude-opus-5 · 1.0M token context ↑↓ move enter next esc back ctrl+c cancel ``` | Question | Answers | | --- | --- | | Model | whatever `GET /v1/models` returns, plus `custom…` for any id | | Effort | the API's own `llm.EffortLevels`: `low` `medium` `high` `xhigh` `max` | | Approvals | ask before every mutating call, or accept them all | | Web search | `none`, Claude's hosted search, or a command on this machine | | Theme | `ember` `mint` `iris` `mono` | | Claude Code login | no, or borrow it when no key is set — asked only where no key or token was given, the endpoint is Anthropic's, and Claude Code is logged in | | Claude skills | leave them alone, use them in place, or copy them once — asked only where there are some | | herdr skill | install it, or not — asked only where herdr is | The last three are the steps that are sometimes not there. The rail knows how many questions this run is actually asking rather than how many the build has, so a machine with none of them gets a five-node rail with no gaps in it, and `step 7 of 8` on a machine with all three counts the questions you are being asked. The Claude Code login question opens on no, and both answers carry the same sentence about the terms: the login is issued to Claude Code, and using it from another client is outside Anthropic's terms for it — so it is a choice for your own machine, described [under Quick start](install.md#quick-start). Someone with an API key set is not asked at all, because there is nothing for them to decide. The answer is `claude_code_auth`; changing it mid-session says it takes effect on the next start, because the client was built, credential and all, before the wizard opened. The herdr answer is also the one that is not a preference: it is an act, carried out once, so nothing about it is written to the config. It appears when `HERDR_ENV=1` or `herdr` is on `PATH`. What it installs, and what happens when the download fails, is [on the hooks page](hooks.md#the-herdr-skill). The Claude skills question is described under [skills](skills.md#claude-codes-skills); "copy them once" is an act in the same way, carried out as the wizard closes, and it is the mode rather than the act that is saved. It is the same catalogue and the same pricing table `/model` uses, through the same `GET /v1/models` call, so the two cannot disagree about what a model is called or what it costs. Where they differ is failure: `/model` reports the error and closes, because there is a session to go back to. The wizard cannot do that on a first run, so it falls back to the models this build can price and says so. `custom…` is there because a gateway may serve something no build has heard of. The theme step previews by applying the palette for real — reading a swatch tells you nothing about what a transcript looks like in it — and it recolours the whole TUI, pickers and slider included. Cancelling puts the old one back. Answers land in `~/.config/codey/config.json` (`XDG_CONFIG_HOME` is honoured): ```json { "version": 1, "model": "claude-opus-5", "effort": "high", "approvals": "ask", "web_search": "custom", "search_command": "ddgs text -q {{query}} -m {{count}} -nc", "claude_skills": "use", "diagnostics": "on", "claude_code_auth": "off", "theme": "ember", "auto_compact": "on", "setup": "done" } ``` `claude_code_auth` is `"on"` or `"off"`, and a missing key — or any other word — means off: the Claude Code login is borrowed only on an explicit `"on"`, or for one run with `-claude-code-auth`, and `-no-claude-code-auth` beats both. A missing key is also how Codey knows it has never asked, which is what the one-time question for someone upgrading reads. `auto_compact` is the one key neither the wizard nor `/settings` offers a row for — set it by hand, or pass `-no-auto-compact` for a single run. `diagnostics` is the one `/settings` has a row for and the wizard does not ask about: it defaults to on, it runs a tool already installed on this machine, and nothing it reads leaves the machine, which is the test every question in that interview is really asking. Both screens write the whole file but only touch what they asked about, so it survives them. Set to `"off"`, the conversation is never folded on its own: the window becomes a wall rather than a trigger, and at `-compact-floor` the turn stops before sending a request that would not fit, naming `/compact` and `/clear` as the ways on. The prompt is refused *before* it joins the history, so compacting and asking again sends it once rather than twice. `/compact` keeps working throughout — the setting governs the automatic fold, not the manual one. Anything other than `"on"` or `"off"` is dropped, and a missing key means on, so a config written before this existed does not suddenly start stopping the agent. Nothing in that file is required, and none of it wins an argument with a flag: precedence is **flag, then config, then the built-in default**, so `-model claude-sonnet-5` is still a one-run override. `accept-all` saved as a default is honoured, but `-yolo` can only turn approvals off, never on — a file should not be able to quietly grant the agent more than the command line did. `-no-auto-compact` runs the same way round: the flag can only turn the automatic fold off, and a config that never mentions it leaves it on. A value this build does not recognise is dropped rather than forwarded to the API, and effort is checked against `llm.EffortLevels` rather than a second copy of the same five strings. `/setup` reopens the wizard at any time. Finishing applies the answers through the same setters `/model` and `/effort` use, so a setting chosen in the wizard and the same setting chosen from the prompt cannot come out different — the wizard just reports them in one line instead of three. It is refused mid-turn: changing the model while a turn is in flight would finish it on a different model than it started. A config file that cannot be parsed is reported and then ignored, and is never overwritten until you finish the wizard. `/model` and `/effort` change the running session and say "from the next turn on"; they do not write to the file. The two screens that do are the wizard and `/settings`. ## Where Codey keeps things Two directories: one global, one per repository. The second sits in your working tree and is git-ignored, because sessions and an event log are yours rather than the project's. | Path | What | | --- | --- | | `~/.config/codey/config.json` | the answers, written by the wizard and `/settings`; [hooks](hooks.md) go here by hand | | `~/.config/codey/trust.json` | which checkouts' [Claude Code files](mcp.md#trusting-a-project) you trusted, and which version of them | | `/.codey/sessions/` | saved conversations, which is what `-resume` and `/resume` read | | `/.codey/events.jsonl` | the event log METRICS.md is built from | | `/.codey/history` | what has been typed at the prompt here, which `↑` walks back through | Codey was called `harness` until recently, and both of those used to live under that name. Neither rename costs you anything. The config is read from `~/.config/harness/config.json` when there is nothing at the new path, so a setup you have already done still counts and the wizard stays shut; that is a read, and the old file is left where it is for an older build to keep using. The per-repository directory is instead moved once, on the first run in a clone that still has a `.harness/`, and Codey says so when it does — the event log is append-only, so leaving half a repository's history under the old name would quietly corrupt the numbers rather than preserve them. A clone that somehow has both keeps the newer one and leaves `.harness/` alone. ## /settings `/settings` is the same settings without the interview: one row each, changed in place, applied as you move. ``` Settings ↑↓ row · ←→ change · esc done ❯ Model Opus 5 $5 / $25 per Mtok Effort high default Approvals Ask me first recommended Web search No web access default Diagnostics On default Claude Code login No, I'll use an API key default Claude skills Leave them alone default Theme ember claude-opus-5 · enter to pick from anthropic saved to ~/.config/codey/config.json ``` `←→` cycles a row and applies it there and then — the theme repaints under the panel, the way it previews in the wizard — and `esc` closes and writes the file. There is no cancel, because there is nothing left to confirm: the session already has every change. A panel that was only read leaves the file alone, and so does a value cycled back to where it started. The rows come from the same option lists the wizard's steps are built from, so neither screen can invent a name for a theme or a sentence about an effort level the other does not use. The model row is the exception: its choices come from the endpoint rather than from this build, so `enter` hands over to the `/model` picker and lands back here once you have chosen. The Claude Code login row is there whether or not the wizard asked, so the opt-in [described under Quick start](install.md#quick-start) can be turned on or back off without rerunning setup. Like web search, diagnostics and Claude's skills, it is decided when the session starts, so a change says it takes effect on the next start rather than pretending to swap the credential under a conversation already in progress. What the panel shows is the *session*, not the file — `/effort`, `shift+tab` and `-yolo` all change a setting without the file hearing about it, and a panel that disagreed with the status bar two lines below it would be worse than useless. Only the rows actually touched are written back, which is what keeps a `-yolo` run from quietly saving "accept everything" as the default for every run after it. And the setup marker is *not* stamped here: changing a theme is not answering the setup questions, so someone who has only ever used this panel is still offered the wizard. The whole thing is `↑↓` and `enter`, `esc` to go back. Animations collapse to their final frame under `NO_COLOR`, a `dumb` terminal, or a window under 60×20, and any key skips the one playing.