Configuration

orangu uses an INI configuration file.

Interactive setup (--init)

Run orangu --init (short form -i) to generate the configuration interactively instead of editing the file by hand:

orangu --init

The wizard:

  1. Asks for the LLM URL (the server endpoint).
  2. Queries the server’s /v1/models endpoint and pre-fills the first advertised model as the Model value; if no model can be detected, you enter one manually.
  3. Walks every [orangu] and server option, showing its default in [brackets]. Press Enter to keep the default. Boolean options accept Yes/Y/No/N (case-insensitive).
  4. Reports which optional external tools it detects (git lg, delta, bat, gh, and glab). Each is shown as No when the tool is absent, Yes (Used) when it is installed and configured to be used, or Yes (Not used) when it is installed but not yet wired up — for example delta installed but not set as your Git diff pager. See Optional external tools for how each one is activated.
  5. Installs bundled skills into ~/.orangu/skills/ when they are not already present. At the moment this includes debugging.
  6. Shows the resulting configuration and asks for confirmation before writing.

The server is orangu-server. Only values that differ from their default are written, so the generated file stays minimal. It is written to ~/.orangu/orangu.conf, creating ~/.orangu/ if needed and overwriting any existing file. Bundled skills are written to ~/.orangu/skills/<skill>/SKILL.md and are left untouched when the file already exists.

Agent Skills

orangu supports Agent Skills: directories containing a SKILL.md file with YAML frontmatter and markdown instructions. Skills are discovered from four locations:

  1. ~/.orangu/skills/
  2. ~/.agents/skills/
  3. <workspace>/.orangu/skills/
  4. <workspace>/.agents/skills/

Project skills override user skills with the same name. The /skills command lists the discovered skills. A skill can be invoked explicitly with /skill-name; for example, the bundled debugging skill is typically available after --init:

/debugging reproduce the failing request path and identify the root cause

See the Skills chapter for how to write instruction-only skills, skills with helper files, and skills that compile helper code.

Startup connectivity

The terminal UI renders immediately on launch — it never waits on a network check first. The header’s Server/Model rows show a white dot while connectivity is still being resolved in the background, turning green or red within a moment.

If the default server ([orangu] server = ...) doesn’t respond, orangu automatically tries the other configured server sections in turn and switches to the first one that does, printing “Switched to server: <name>” to the output window. If none of them respond either, it stays on the default (which then shows red, as usual). This happens once, at startup; /server still switches on demand exactly as before.

Per-session server and model

Each workspace tab keeps its own active server, model, and endpoint. A /server or /model command in one tab does not affect any other tab, and switching tabs restores the server and model that were active there.

These choices are persisted automatically. When you run /server or /model, the selected values are written to the session’s settings file:

~/.orangu/sessions/<UUID>/settings

The next time that session is resumed — whether in a new run or after a tab switch away and back — orangu restores the server and model from there. No manual config files are needed.

[orangu]

The main section selects the default server and client-wide limits. The server key names the server section that holds the host information:

[orangu]
server = main-server
model = ggml-org/gemma-4-E4B-it-GGUF
timeout = 1800
max_tool_rounds = 10
review_max_tokens = 512
code_max_tokens = 0
theme = classic
Key Required Description
server Yes, if multiple servers exist Name of the default server section
model No General default model name. Used unless the selected server defines its own model, which takes precedence
timeout No Request timeout in seconds. The default is 1800
max_tool_rounds No Maximum tool-calling turns before the client aborts the prompt
review_max_tokens No Response-token cap for each /auto_review request. Defaults to 512; 0 disables the cap. Raise it (e.g. 2048) when the review model thinks before answering
code_max_tokens No Response-token cap for normal chat and tool responses. Defaults to 0 (no cap)
compile_workers No Parallel job count /build passes to toolchains that support one (e.g. make -j, meson compile -j, cargo --jobs). Defaults to 0, meaning unused: no job flag is passed and each toolchain falls back to its own default
quotes No Quote set shown while the model is thinking. Defaults to none. Options: none, star_trek, star_wars, marco_pierre_white, gordon_ramsay, calvin_and_hobbes, sun_tzu_mandarin, sun_tzu_english, attila_the_hun, all
width No Virtual terminal width in characters. Controls the layout canvas for /show_file output. Defaults to 512
banner No Horizontal placement of the banner. Defaults to left. Options: left, center, right
theme No Global default UI theme. Defaults to classic. Built-ins are classic, modern_dark, modern_light, oranguday, tokyonight, and rosepine-moon; random draws one of the available themes at each launch. User themes are loaded from ~/.orangu/themes/*.theme
drop_down No Enable the autocomplete dropdown for slash commands. Defaults to on. Options: on, true, 1, off, false, 0
word_wrap No Wrap long lines in the main TUI, /show_file, /review, and /auto_review windows. Defaults to off; set it to on to wrap at the visible width. Options: on, true, 1, off, false, 0
mouse No Enable mouse capture in the terminal. When true (the default), the TUI handles mouse scroll and double-click. Hold Shift while clicking/dragging to do native text selection and copy. Set to false to disable all mouse handling
workspaces No Placement of the workspace tabs. Defaults to top. Options: top, bottom, left, right. See the Workspaces chapter
feedback No Show a green or red dot in the output window after each command to indicate success or failure, blink an orangu ● progress title and ring the terminal bell when a /auto_review finishes. Defaults to off. Options: on, true, 1, off, false, 0
auto_rebase No Automatically rebase the branch before /pull_request if it is behind the base. Defaults to off. Options: on, true, 1, off, false, 0
auto_squash No Automatically squash commits before /pull_request if more than one commit is ahead of the base. Defaults to off. Options: on, true, 1, off, false, 0
terminal No Launch command used to open $EDITOR for terminal editors in a new window for /open_file (for example xterm -e or kitty). When unset, a terminal emulator is auto-detected
platform No Code-hosting platform driven for /pull, /pull_request, /merge, and /comment. Defaults to github (uses the gh CLI). Options: github, gitlab (uses the glab CLI)
system_prompt No Override the base system prompt sent to the model. When empty (the default) orangu uses its built-in coding-assistant prompt. The discovered Agent Skills index is appended to whichever prompt is in effect
review_confidence_threshold No Minimum confidence score (0–100) for /auto_review findings; findings below this threshold are silently dropped. Defaults to 80. Set to 0 to disable filtering
compression No Enable the built-in compression layer: context deduplication, file-read stubbing, and shell-output compression. Defaults to on. Options: on, true, 1, off, false, 0. See the Compression chapter
auto_downsample_lines No Line count above which an unbounded file read is returned as signatures instead of the whole file, with a note saying so. Defaults to 300; 0 reads every file in full. Only applies while compression is on, and never to a read that asked for a mode or a line range
diff_file_cap No Maximum number of files kept when a git diff is compressed. Defaults to 20. See the Compression chapter
world_state_max_bytes No Ceiling on the world_state_changes fragment prepended to a turn when the working tree has changed, in bytes. Defaults to 8192; 0 disables the cap. See Workspace change budget
semantic_budget_tokens No Token budget for the code chunks /search injects into a turn. Hits are added in rank order until the next one would exceed it, so the cap bounds what semantic search costs in context rather than the number of results. Defaults to 16384; the top hit is always kept

Workspace change budget

Every interactive turn taken after the working tree changed carries a world_state_changes fragment describing the change. That fragment is prefilled by the server, so its size is response latency, not just context: on a small local model a few hundred bytes cost milliseconds and a few hundred kilobytes cost minutes.

world_state_max_bytes is the hard ceiling on it. Raise it if you want the model to see more of a large working diff without asking; lower it if the first turn after each edit feels slow. Two lower limits apply before it — untracked files above 4 KiB are announced rather than inlined, and smaller ones are cut to 80 lines — so the ceiling is rarely the binding constraint in an ordinary workspace. The Compression chapter describes the whole path.

Response-token caps

review_max_tokens and code_max_tokens bound how long a model response may get. Each is sent to the server as the max_tokens field of the chat completion request, so the server stops generating when the cap is reached — the request does not fail, the response is simply cut off at that point. A value of 0 disables the cap entirely: no max_tokens field is sent and the server’s own default applies. Like timeout and max_tool_rounds, both keys are client-wide and apply to every configured server.

The two caps cover the two kinds of request the client makes:

A cut-off answer says so. Whichever cap is reached, the server reports finish_reason: "length" and orangu prints [answer cut off at the server's response-length cap …] under the timings. This matters most on a tool-calling turn: a file’s contents travel inside the tool call, and a call cut off mid-argument never closes, so it is not recognised as a call at all — nothing runs, nothing is written, and the half-finished file arrives as ordinary text. If you see that notice where you expected a file, raise code_max_tokens.

Reasoning (“thinking”) models need a larger review cap. A model’s hidden thinking tokens count against max_tokens, so with the default 512 a model that deliberates at length can be cut off before it emits its verdict. Such a truncated review is handled safely — a response with no verdict and no findings is recorded under Overall as a failed category review and the file keeps its white (unreviewed) box, so a truncation can never silently approve a file — but the review is wasted. When reviewing with thinking enabled, raise the cap so the answer survives the thinking:

[orangu]
review_max_tokens = 2048

Conversely, for the fastest reviews disable thinking on the server (orangu-server --reasoning-budget 0 together with --chat-template-kwargs '{"enable_thinking": false}') and keep the default 512 — the cap then almost never binds and only guards against runaways.

Themes

The global default theme is configured in [orangu]:

[orangu]
theme = classic

Built-in themes are shipped inside the binary: classic, modern_dark, modern_light, oranguday, tokyonight, and rosepine-moon. modern is accepted as a short name for modern_dark.

random is not a palette of its own: it draws one of the available themes — the shipped ones plus anything in ~/.orangu/themes — when it is applied, and holds it for the rest of the run, so the UI never reshuffles mid-session. The configuration or session value stays random, so the next launch draws again.

A theme selects both a palette and a chrome — the screen furniture around the content:

chrome Frame
classic (the default) The boxed ORANGU banner pinned to the top of the screen, placed by the banner key; the output window directly below it at full width; and full-width separators above and below the input window
modern The banner only on the empty landing screen; an inset output window; code blocks drawn in a box; and a rounded input box

Both frames share the rest: the input window carries a bare > prompt, and closes with the same status line, which shows the branch on the left, a centered Graph: / Pending: group, and the model name flush right.

classic and the modern_* themes differ only in this: they are the same UI in the two frames, so theme = modern_dark is the way to keep the Ratatui-native look while theme = classic reproduces the original one.

Custom themes live in:

~/.orangu/themes/<name>.theme

A theme file is key = value lines. Colours are #RRGGBB, or default to leave the terminal’s own colour in place; styles accept fg:/bg: colours plus bold, italic, underlined and reversed. The chrome key takes classic or modern.

Every key is optional, and classic is the base. Whatever a file leaves out keeps its classic value, so a theme that only wants a different link colour is one line long:

highlight = fg:#66b2ff

That also means a palette-only theme never changes the layout by accident, and that adding a key in a later release never invalidates the theme files already on disk. A key that isn’t recognized is an error rather than a silent no-op, so a typo can’t quietly fall back to the classic value.

You can switch the current session with /theme <name>. That writes a session override to:

~/.orangu/sessions/<UUID>/theme

Naming the theme orangu.conf already asks for drops the session override instead of pinning a copy of it, so the session goes back to following the global [orangu].theme. The command completes built-in themes and user theme files. The startup option -t/--theme <name-or-path> applies a theme only for that process and takes precedence over the global and session settings.

The session’s licence

The licence generated files are written under is a session setting too, but it is not configured here: it is read from the workspace — its manifest’s license field, then its LICENSE/COPYING file, then MIT as the default — and overridden for the session with /license <spdx> [<holder>]. That writes:

~/.orangu/sessions/<UUID>/settings

as license and license_holder, beside the session’s server and model, and is restored on resume or when you switch back to that workspace tab. /license auto clears it and /license none turns headers off. See the Core tools chapter.

Server sections

Each server is a named section. The section name is what [orangu].server points to, and it carries the host information for that server:

[main-server]
endpoint = http://localhost:8100/v1
model = ggml-org/gemma-4-E4B-it-GGUF
Key Required Description
endpoint Yes orangu-server URL (its OpenAI-compatible API)
model No Model identifier used in chat completion requests. Overrides the general [orangu].model when set
api_key No API key sent as Authorization: Bearer <key> on every request to the server. Required when orangu-server runs with --api-key
role No A specific role this server fulfills. Valid roles are: all (default), code, review, explorer, and embeddings. If a specific subsystem needs a server and one is tagged with its role, it will use that server instead of the default. embeddings designates the server that embeds code for semantic /search; an all server also serves it, and search auto-enables when that endpoint responds at startup. Ignored behind a confirmed orangu-coordinator — it alone decides which model backs each role, so a single server section is enough there
model_verbosity No How chatty this server’s model should be. Defaults to normal. Options: terse, normal, verbose. It is a per-server key: writing it in [orangu] has no effect

Sample file

The distributed sample lives at:

doc/etc/orangu.conf

It ships with orangu-server sections and a 30-minute timeout suitable for local tool-calling workloads.

MCP servers

Use a [mcp.<name>] section, or set mcp = true in a section, for an already-running Streamable HTTP MCP service. The endpoint normally ends in /mcp.

[mcp.weather]
endpoint = http://localhost:9000/mcp
timeout = 30
approval_mode = writes
Key Required Description
endpoint Yes Streamable HTTP URL of the running service, normally ending in /mcp
mcp Only for the shortcut form Set to on in a section that is not named mcp.<name> to read that section as an MCP service too. Options: on, true, 1, off, false, 0
timeout No Seconds allowed for initialization, tool discovery, and tool calls alike. Defaults to 30, and supplies the default for the two keys below
startup_timeout No Seconds for connection and tool discovery alone. Defaults to timeout. Must be greater than zero
tool_timeout No Seconds for a single tool call. Defaults to timeout. Must be greater than zero
enabled No Whether the service is used at all. Defaults to on. Options: on, true, 1, off, false, 0
required No Make a failed connection abort workspace startup instead of disabling the service with a warning. Defaults to off. Options: on, true, 1, off, false, 0
enabled_tools No Comma-separated allowlist of tool names. Empty (the default) offers every discovered tool
disabled_tools No Comma-separated denylist of tool names. The denylist wins over enabled_tools
approval_mode No How tool calls are confirmed. Defaults to auto. Options: auto, prompt, writes, deny

The section name after mcp. is the service name used in the mcp__<server>__<tool> prefix, and it accepts ASCII letters, digits, _ and -. Configuring the same name twice — once as [mcp.<name>] and once through the mcp = on shortcut — is a startup error.

approval_mode controls MCP execution: auto runs tools directly, prompt asks for each call, writes asks unless the MCP tool declares readOnlyHint, and deny disables the service. In the interactive terminal, answer an approval with y or n; noninteractive and review runs deny calls that require confirmation.

orangu connects to configured MCP services; it does not launch or manage MCP processes. A failed service is disabled with a warning while the rest of the session continues. MCP support is tools-only: resources, prompts, sampling, elicitation, and tasks are deferred. Use /mcp refresh to rediscover tools after a service changes them; an interrupted connection is retried once.