Configuration
Plain JSON files you can edit by hand, a /config panel when you'd
rather not, and a strict precedence order so there is never a mystery about which value wins.
File locations and precedence#
| Scope | Path | Use for |
|---|---|---|
| User | ~/.khaelor/config.json | Your personal defaults across all projects |
| Project | .khaelor/config.json | Per-repository settings and permission grants (commit it if the team shares them) |
Values merge with this precedence (highest first):
CLI flags → project config → user config → environment → built-in defaults
So khaelor --model claude-opus-4-5 overrides everything for that session, a
project's .khaelor/config.json overrides your user file, and the environment is
consulted only for the API key.
All settings#
| Key | Type | Default | Meaning |
|---|---|---|---|
model | string | claude-sonnet-4-5 |
The Anthropic model id (or alias) used for agent turns. Never a hard-coded permanent list — any current Anthropic model id works. |
auxModel | string | claude-haiku-4-5 |
A cheaper Anthropic model used for auxiliary work such as context-compaction summaries. |
thinking | string | adaptive |
Extended-thinking mode: off, adaptive (the model thinks when the task warrants it), or always. |
maxOutputTokens | integer | 16000 |
Output token budget per model response. Also visible/cyclable in /model with o. |
permissions | object | {} |
Permission rules — capability → allow / ask / deny, with optional per-subject patterns. Full syntax in Permissions. |
A complete example:
{
"model": "claude-sonnet-4-5",
"auxModel": "claude-haiku-4-5",
"thinking": "adaptive",
"maxOutputTokens": 16000,
"permissions": {
"file.read": "allow",
"process.execute": {
"npm test": "allow",
"npm run *": "allow",
"*": "ask"
}
}
}
Unknown fields are ignored (forward compatibility). Malformed values fail loudly at load time with the offending file and field named.
The API key#
The Anthropic API key comes exclusively from the environment:
export ANTHROPIC_API_KEY=sk-ant-...
Config files that contain an apiKey / api_key /
anthropicApiKey field are rejected at load time — the error names
the field but never echoes its value. This makes it structurally hard to commit a key to a
repository. The key is never displayed, never logged, and redacted from every debug view;
/config shows only set via environment ✓.
Choosing a model#
Three equivalent ways, highest precedence first:
- Per session:
khaelor --model <anthropic-model-id> - Interactively:
/model— pick from your configured models/aliases, cycle thinking with t and the output budget with o; applies immediately and shows in the status bar. - Persistently: set
modelin the project or user config file.
Because Anthropic model identifiers evolve, KHAELOR ships no permanent hard-coded model list — the defaults are aliases you can override anywhere.
Thinking mode and output budget#
thinking: "off"— no extended thinking; fastest and cheapest.thinking: "adaptive"(default) — the model uses extended thinking when the task warrants it. While it thinks, the status line shows a compact● Thinking · 4s— thinking is never the centerpiece of the UI.thinking: "always"— maximum deliberation on every turn.
maxOutputTokens caps each response. The context inspector
(/context) shows this as the "reserved output" slice of the window, so you can see
exactly what a larger budget costs you in usable context.
The /config panel#
┌─ config ── ~/.khaelor/config.json · .khaelor/config.json ─┐
❯ Model claude-sonnet-4-5
Thinking adaptive
Max output 16000
Permissions 12 rules →
Theme khaelor-dark
API key set via environment ✓
└──────────────────────────────────────────────────────────┘
↑↓ navigate · Enter edit · p project scope · Esc close
Edits write to a real config file — p toggles between user and project scope, and the target file is always shown before writing. The files remain the source of truth; the panel is just a convenient editor over them.
Project instructions#
KHAELOR automatically discovers project-level instruction files and folds them into the
agent's context: KHAELOR.md is the native format, with compatibility for
CLAUDE.md and AGENTS.md. Precedence flows from general to specific —
instructions closer to your working path refine global ones:
~/.khaelor/KHAELOR.md → repository/KHAELOR.md → nested/directory/KHAELOR.md
Use them for repository conventions: build commands, test invocations, style rules, "never
touch these files". The /context inspector shows exactly how many tokens your
instructions occupy.
Everything else under ~/.khaelor/#
| Path | Contents |
|---|---|
~/.khaelor/config.json | User configuration |
~/.khaelor/sessions/ | Persistent session event logs (JSONL) |
~/.khaelor/prompt-history.jsonl | Composer history, per project |
~/.khaelor/tool-output/ | Spilled full tool output, session-scoped, auto-pruned |
~/.khaelor/process-logs/ | Complete background-process logs |
~/.khaelor/logs/ | Developer logs (with --debug); never pollute the TUI, never contain secrets |