Settings reference

Every rootle setting: key, acceptable values, meaning, default. Config lives at ~/.config/rootle/config.toml ($ROOTLE_CONFIG does not apply — use rootle --config PATH for an alternate file). Missing keys fall back to defaults; malformed configuration is reported in the status line without blocking startup. The :settings popup edits these in place and writes the same file — hot-reloads the theme on save. Sections live in a sidebar (Tab/h/l); themes and the provider kind are radio lists, booleans are ●/○ dots, and text fields edit in place — ␣/enter activates the row. Committing a theme recolors the popup immediately. Provider changes save too but apply after restart.

[editor]
program = "hx"          # string, optional
args = []               # list of strings
read_only = true        # boolean

[theme]
name = "catppuccin-mocha"   # string
# path = "/abs/or/~/theme.toml"   # string, optional — overrides name

[cache]
max_mb = 512            # integer

[provider]
kind = "github"         # "github" | "stdio"
command = []            # list of strings (kind = "stdio")
timeout_ms = 30000      # per-request read deadline (kind = "stdio")
# stderr = "inherit"    # pass child stderr through (kind = "stdio")

[editor] — opening files

Key Type Default Meaning
program string, optional unset Editor binary. Unset → $VISUAL → $EDITOR → first of hx, nvim, vim, vi on PATH.
args list of strings [] Extra arguments inserted before the file path.
read_only boolean true With true, the vim family (vim, nvim, vi, view) opens with -R. Editors without a read-only flag (e.g. helix) edit the cache copy — rootle never writes back either way.

Files open from ~/.cache/rootle/edit/<owner>__<repo>/<path>; rootle suspends the terminal while the editor runs and fully redraws on return.

[theme] — colors

Key Type Default Meaning
name string "catppuccin-mocha" Palette to load. Embedded dark: catppuccin-mocha, dracula, gruvbox-dark, nord, one-dark, solarized-dark, tokyo-night. Embedded light: catppuccin-latte, github-light, one-light, solarized-light. Unknown name → Catppuccin Mocha.
path string, optional unset Explicit palette file; wins over name.

--theme NAME (CLI) overrides name for one session. To write your own palette, place a TOML file under ~/.config/rootle/themes/ with [semantic] role names mapped to hex colors, or select it with path.

Since v0.11.0, syntax highlighting uses statically linked Tree-sitter grammars and maps captures onto the active palette. A palette change recolors cached previews automatically.

The embedded set covers Rust, Python, JavaScript/JSX, TypeScript/TSX, Go, C/C++, Java, C#, Ruby, PHP, Bash, Lua, JSON, TOML, YAML, HTML, CSS and Markdown. Supported-language Markdown fences and HTML scripts are highlighted with their embedded grammars. Unknown file types remain plain text. No grammar downloads or shared-library installation are needed.

Commit deltas use diff_add_fg, diff_del_fg, diff_add_bg, diff_del_bg, diff_add_strong, diff_del_strong and diff_band. Unspecified diff colors follow the active light/dark palette; explicit overrides win.

Commit inspection

Select or open a repository and press ␣ h to see its commits at the current branch/tag. d opens commit detail in both repository and file history. For a single file, ␣ p focuses the preview and h opens history; Enter there opens the file at the selected commit, not commit detail.

The changed files form an expanded directory hierarchy on the left. Directory headings are not selectable; j/k and ]f/[f move between matching file leaves. Enter opens the selected diff and focuses it. Tab switches between files and preview; narrow terminals stack the panes.

Commands follow the focused pane:

Key Files Diff preview Message preview
/ Filter full paths, old rename paths and status Incremental literal, case-insensitive find —
n / N — Next / previous match, wrapping —
y Commit permalink Revision-pinned source-line link; headers use the commit link Commit permalink
Y — Copy the source line, without diff gutters Copy the full message
h / l — Horizontal scrolling —
Ctrl-d/u, Ctrl-f/b, Page Down/Up — Half/full-page movement Half/full-page scrolling
? Keybinding catalog Keybinding catalog Keybinding catalog

Deleted-line links use the first parent revision and the old rename path. Links require provider support; unavailable links report an error rather than inventing a URL. Esc cancels a find edit or clears committed find highlights before closing the diff; sidebar filters clear while the sidebar owns focus. Further Esc presses unwind to history and the browser.

Diffs retain add/delete and changed-span background tints under Tree-sitter syntax colors. Highlighting uses the available old/new hunk fragments; it does not fetch or reconstruct missing whole-file context.

Providers may omit binary or large patches or truncate a file list. Those states are labeled; an unavailable patch is not an empty change. The viewer is read-only and never stages, commits or reverts code.

Fresh profiles and input modes

Fresh profiles start with repository search and no seeded organizations or repositories. Existing user recents are preserved. Modal search fields show ❯ in INSERT and ● in NORMAL; Esc switches to NORMAL and i returns to INSERT. Transient / filters still cancel directly on Esc.

[cache] — content store

Key Type Default Meaning
max_mb integer 512 Blob cache cap in MiB. Least-recently-used blobs are evicted past it at startup; orphaned trees/blobs are swept.

Blobs/trees are content-addressed and immutable (never invalidated, only evicted); repo refs revalidate via ETag (a 304 is free). The GitHub provider's store lives at ~/.cache/rootle/providers/github/ (the TUI-level edit/ scratch stays at ~/.cache/rootle/); deleting either is always safe. stdio providers manage their own caches under ~/.cache/rootle/providers/<name>/.

[provider] — backend selection

Key Type Default Meaning
kind "github" | "stdio" "github" github = the built-in provider. stdio = external child process speaking NDJSON-RPC (provider-protocol.md).
command list of strings [] argv for kind = "stdio"; element 0 is the executable, the rest its arguments. Ignored for github.
timeout_ms integer 30000 Per-request read deadline for kind = "stdio": a hung backend call fails with a timeout instead of wedging the provider.
stderr "null" | "inherit" "null" inherit passes the stdio child's stderr through — adapter debugging without a log file.

Invalid/misfiring stdio configuration falls back to github with a warning in the status line — a provider misconfiguration never blocks startup. Scaffolding a provider: skills/rootle-provider.

Session diagnostics

Available since v0.11.0, these switches work with the TUI, headless scripts, provider commands and self-update:

rootle --log
rootle --log-file issue.jsonl owner/repo
rootle --headless steps.txt --log-file issue-full.jsonl --log-content

--log / --log=ALL prints an automatically selected path under the state directory's rootle/logs/. --log=PATH or --log-file PATH selects a new file and overrides ROOTLE_TRACE. Existing files/symlinks are refused, never overwritten or appended; Unix files are private (0600).

Metadata records modes, focus, cursors, selections, worker/request identities, HTTP/cache outcomes, errors and cell/style hashes. It excludes typed text, file text, rendered glyphs and provider stderr. --log-content opts into sensitive input/UI/stderr capture; inspect it before sharing. Neither mode automatically dumps env values, argument vectors, authorization headers or raw RPC/HTTP bodies. Metadata can still reveal private repository paths.

Files end with a trace_end verdict. Missing markers, capture failures and limits mean incomplete; a complete capture can still describe a failed command. Storage is bounded to 64 MiB, 100,000 events and 256 KiB per record. This supplies evidence for investigation, not deterministic remote replay.

Environment variables

Variable Meaning
ROOTLE_TOKEN, GITHUB_TOKEN GitHub token (GitHub provider only; gh auth token is tried after these). Code search requires a token.
VISUAL, EDITOR Editor fallbacks when [editor].program is unset.
ROOTLE_CLIPBOARD Path to a file — yanks (␣ y) write there instead of the clipboard (scripts/CI).
ROOTLE_TRACE Path for a new private JSONL diagnostic session; existing files are refused.
ROOTLE_HEADLESS_COLS, ROOTLE_HEADLESS_ROWS --headless viewport (default 100×30).
NO_COLOR Ignored by the full-screen TUI, whose colors are semantic. Provider-management and update CLI output honor it.

Updating rootle

Since v0.12.1, application and provider commands have explicit ownership:

rootle self-update          # application only
rootle self-update --check  # report without replacing the executable
rootle update               # application, then managed providers
rootle provider update      # refresh provider version metadata
rootle provider upgrade --all

Tarball/install.sh installations replace rootle after checksum verification. Homebrew, Cargo and mise installations receive their package manager's upgrade command instead.

Upgrading a v0.12.0 tarball: run rootle --update once. That release's rootle update incorrectly selected provider maintenance; the long flag reaches its existing application updater. self-update is available after installing v0.12.1. Package-managed users should use their normal upgrade command, such as brew upgrade rootle or cargo install rootle --locked.

Command line

rootle                    # launch (search popup only on fresh state)
rootle owner/repo         # skip the popup, open a repo
rootle --config PATH      # alternate config file
rootle --theme NAME       # override [theme].name for this session
rootle --headless SCRIPT # scripted driver: keys in, frames + state JSON out (no terminal; `-` = stdin)
rootle --version | -V

Headless scripts

--headless SCRIPT reads one directive per line; - reads stdin. Blank lines and lines starting with # are ignored:

Directive Meaning
keys <text> Send keys, including <esc>, <cr>, <bs>, <tab>, <space> and arrow-key tokens.
settle [ms] Wait for outstanding workers and queued follow-ups; default timeout 10000ms.
wait <ms> Process events for a fixed duration.
frame Print the rendered cell grid.
state Print JSON describing the current app state.

For a tree-rendering CI check:

printf 'settle\nframe\nstate\n' | rootle owner/repo --headless -

Startup waits for outstanding work, with a 10-second bound. Use settle after navigation and before sampling frame or state. Its optional argument changes the timeout for that step, not startup. A timeout exits nonzero and stops the script before later samples. Completion includes failures: inspect state.status and the rendered frame to distinguish a populated tree from a provider error.

Since v0.11.0, settle tracks real work rather than guessing from channel silence. Older releases used a 400ms quiet window and could return while a slow provider was still loading. All directives are listed in --help.

Where things live

Path Contents
~/.config/rootle/config.toml configuration
~/.config/rootle/themes/<name>.toml palette overrides ([semantic] role = hex)
~/.local/state/rootle/state.json recents, last org/repo/path, last search scope/extension
~/.cache/rootle/edit/ files materialized for your editor
~/.cache/rootle/providers/<name>/ per-provider content cache (safe to delete)

Cache layout: trees/<sha>.json (immutable repo trees), blobs/<ab>/<rest> (blobs sharded by the first two sha chars), index/refs/<owner>/<repo>/<branch> (rev → tree sha + etag, revalidated on open), edit/ (materialized files). At startup rootle sweeps orphans and evicts least-recently-used blobs past [cache].max_mb (default 512). Deleting ~/.cache/rootle is always safe; state and config are separate files.