Configuration
TOML, merged in this order (later wins per field, not per file — setting one field in the repo file doesn’t reset the rest of a section back to whatever the home file or the built-in default had it at):
- built-in defaults
~/.config/katamari/config.toml<repo_root>/.katamari/config.toml
An unrecognized key warns once to stderr and is otherwise ignored — a typo or a field from a newer katamari version never stops a session from starting. All sections are optional.
One exception to “later wins per field”: [agent] adapter (below) is
honored only from the home file, never the repo file — see its own note.
# Which built-in keymap preset to start from.keymap = "vim" # or "emacs"
[keys]# Action name (kebab-case; see the keybindings table in the Keybindings# chapter for what each one does) -> key-sequence notation, overriding the# preset above.# Notation: "C-x" (Ctrl), "M-x" (Alt/Meta), "Space"/"Esc"/"Enter"/"Tab"/# "BackTab"/"Backspace"/arrows/Home/End/PageUp/PageDown as named keys, a# bare character otherwise, space-separated for a multi-key sequence.quit = "Z Z"next-hunk = "C-n"
[lsp]# Whether a missing language server is silently downloaded/built into# katamari's own prefix instead of just reporting an install hint. Default# true; see the Language servers chapter for what each language's strategy# is.auto_install = true
[lsp.logging]# TUI-only combined session journal; headless doctor/lsp-check do not create one.enabled = truesegment_bytes = 5242880segments_per_session = 4total_bytes = 104857600max_age_days = 2
[lsp.servers.rust]# Overrides how a language's server is resolved — highest priority, above# PATH and every project-local lookup. `<id>` is rust/typescript/python/# go/kotlin/java for a built-in override, or any other id of your own# choosing to define a custom server for a filetype katamari has no# built-in support for — see the Language servers chapter's "Custom# language servers" section.command = "/opt/homebrew/bin/rust-analyzer"args = []# extensions/root_markers/language_id/initialization_options — all# optional, all snake_case, normally only set on a *custom* id (a built-in# override like this `rust` entry needs none of them). See the Language# servers chapter's "Custom language servers" section for what each does# and a worked example. A whole# [lsp.servers.<id>] entry replaces wholesale on merge (the repo file's# entry for one id fully replaces the home file's entry for that same id,# not a field-by-field merge) — sibling ids are untouched either way. A# custom id can never claim a file extension one of the six built-in# languages already owns.
[ui]# Terminal columns a tab expands to; ColumnMap (cursor/LSP positions) and# rendering always agree on this value. Default 4.tab_width = 4# Above this many changed lines, a diff file's syntax highlighting is# skipped in favor of plain styling (and it's excluded from LSP warm-up) —# lockfiles (*.lock, package-lock.json, *.min.js) always skip regardless# of size. Default 5000.highlight_max_lines = 5000# Soft-wrap a content line wider than its pane onto continuation rows# (marked with ↪) instead of truncating it at the pane edge. Default true;# set false to restore truncation, e.g. if you rely on it for# alignment-heavy code.wrap = true# Shows the key-display overlay chip described in the Keybindings chapter# by default, without needing `--show-keys` on every invocation. Default# false.show_keys = false# Enables mouse capture (wheel scrolling — see "Mouse" in the Keybindings# chapter). Default true; set false to leave the terminal's own# click-and-drag text selection working instead.mouse = true# Resting the pointer on an eligible code symbol or changed-file tree row# shows details after ~400ms, independently of click/wheel/right-click# support above — see "Mouse" in the Keybindings chapter. Default true;# only ever has anything to act on while `mouse` (above) is also true.mouse_hover = true
[diff]# Overrides `ktmr diff --branch`/the scope menu's "Branch vs base" entry's# automatic base detection (jj trunk() / git origin/HEAD / local main /# local master — see the Quickstart chapter) outright. When set, this is# authoritative: a value that doesn't resolve to a real ref/revset in the# repository is a hard error, never a silent fallthrough to the chain it# replaces. Useful for a repo whose trunk isn't named "main" (or has no# `origin` remote at all) — safe to commit in a repo-local# .katamari/config.toml, unlike [agent] below.base = "develop"# Whether an agent CLI's own disposable in-repo worktree (e.g. a pruned# .claude/worktrees/<name>/ that's lost its .git, so the nested-checkout# rule below no longer protects it) is hidden from both the working-tree# diff and the live-refresh watcher. Default true. The built-in list:# .claude/worktrees/ (Claude Code's current documented default),# .claude/worktree/ (an older/alternate singular form, kept as harmless# insurance), and .codex/worktree(s)/ (speculative — Codex's real worktree# root lives outside any repo, so these are insurance too, not an observed# convention). Untracked-only either way: a file you actually commit under# one of these paths always reviews normally, filtering on or off.## Honored from a repo-local .katamari/config.toml like `base` above, unlike# [agent] below — a deliberate choice, not an oversight: this field can# only narrow an already-documented, untracked-only default exclusion (it# can never widen it into hiding tracked content, and `false` disables# filtering, it can't invent new filtering), and every session where# something is actually hidden gets a status-bar note naming the count and# the matched prefix(es) — the concealment risk a repo-local value like# this could otherwise pose is met with disclosure, not a scope# restriction.agent_workspaces = true# Extra repo-relative path prefixes appended to (never replacing) the# built-in list above — for a tool it doesn't cover, or a convention of# your own. Default empty. Merges by concatenation across the home and# repo config layers (unlike `base`'s plain override-wins), so a global# entry set once in ~/.config/katamari/config.toml survives a repo that# also sets its own. Same repo-local trust decision as agent_workspaces# just above: any prefix added here still only narrows what's shown, and# still always shows up in the same startup note. Matching is a# component-wise, case-sensitive prefix check (Path::starts_with) with no# normalization — a case mismatch (a typo, or a case-insensitive# filesystem) simply fails to match rather than filtering anything, so# double-check the casing against what `git status` actually reports. A# blank or whitespace-only entry is dropped rather than kept (an empty# prefix would otherwise match, and hide, every untracked path).# agent_workspace_extra = ["vendor/agent-scratch"]
[watch]# Debounce window for live refresh: how long a burst of filesystem changes# must go quiet before the diff refreshes. Milliseconds, default 200.debounce_ms = 200
[update]# Whether ktmr looks for a newer release: a once-a-day background check# (never on the critical path — it can't slow a session down or block on a# flaky network) against GitHub, plus the notices sourced from its cached# result — a status-bar note at startup and a one-line "vX.Y.Z is# available — <upgrade command>" hint on stderr when you quit, printed only# if stderr is a real terminal. Default true; false disables both the# request and the notices entirely.check = true
[skill]# Whether saving your first comment in a repo without the full katamari# review harness installed (skill + AGENTS.md + CLAUDE.md) offers to# install it (see the Quickstart chapter). Default true; false turns off the# offer entirely. `ktmr skill install` always keeps working as an explicit# command either way.offer_install = true
[units]# Review units (see the Review units chapter): which agent CLI `u` spawns to# group the diff, and what model/effort it runs with. All optional — with# no [units] table in either config file, the first `u` that would spawn a# CLI opens a one-time picker that writes this section for you.# "claude" or "codex". Unset: whichever is installed, claude first — and a# preference that isn't installed falls back to that same detection order# rather than failing.agent = "claude"# Passed verbatim to `claude --model` / `--effort`. claude_model defaults# to "sonnet" even when the key is absent; an explicit "" drops the# --model flag entirely, deferring to the CLI's own default. An unset# effort adds no flag.claude_model = "sonnet"claude_effort = "high"# The codex equivalents map to `codex exec --model` and# `-c model_reasoning_effort=`; unset means no flag, leaving the CLI's own# configuration in charge.# codex_model = "gpt-5-codex"# codex_effort = "medium"
[agent]# The command that speaks ACP (Agent Client Protocol) for `a`/`A`/`p` (see# "Ask the agent" in the Keybindings chapter) — split on whitespace# (program, then args). Unset resolves `claude-agent-acp` on PATH, then# `npx -y @agentclientprotocol/claude-agent-acp`.## Honored ONLY from this home file, never a repo-local# .katamari/config.toml, unlike every other section on this page —# deliberately: `adapter` is an unrestricted shell command, so allowing a# repo-local file to set it would let a cloned repository silently choose# which command every `ktmr diff` session in that clone executes, the# moment you open it. `[units] agent` above has no such risk (it only ever# picks between two already-installed, well-known binaries by name); a# repo-local `[agent]` table is parsed just enough to warn about it, then# discarded.# adapter = "claude-agent-acp"