respect_gitignore = false # default: false; set true to make every tool skip gitignored files
```
#### Input Mode
The `simple_mode` setting under `[ui]` controls how you edit text in the
**prompt** — the input editor. It does not change how you navigate the
scrollback; that is governed separately by [`vim_mode`](#vim-mode).
| Value | Behavior |
|-------|----------|
| `true` (default) | **Readline editing.** The prompt uses plain readline-style text entry. |
| `false` | **Vim editing (experimental).** The prompt uses vim-style modal editing (normal and insert modes). When the prompt is empty, it starts in normal mode with focus on the scrollback. |
To switch the prompt to vim-style editing:
```toml
[ui]
simple_mode = false
```
You can also toggle this setting from the settings pane (`/settings` →
**Disable vim input mode**); Grok writes your choice to `[ui] simple_mode` in
`config.toml`.
`simple_mode` and `vim_mode` are independent: `simple_mode` changes the prompt
editor, and `vim_mode` changes scrollback navigation. See [Keyboard Shortcuts](03-keyboard-shortcuts.md)
for the full binding reference.
#### Default Selected Permission
When the agent asks for permission to run a command (or other tool action),
the approval menu highlights one row by default — the cursor row. The
`default_selected_permission` setting under `[ui]` controls which row that
is on the **first** prompt of a session.
| Value | Preselected row |
|-------|-----------------|
| `always_allow_all_sessions` (default) | The "Always allow on all sessions" row. |
| `allow_command_always` | The "Always allow this command" row. |
| `allow_once` | The "Yes" / allow-once row. |
| `reject` | The reject row. |
```toml
[ui]
default_selected_permission = "allow_once"
```
After you answer the first prompt, the cursor becomes **sticky**: each later
prompt preselects the same kind of choice you last confirmed (e.g. once you
pick "No", subsequent prompts start on their reject row), carrying across edit
/ bash / MCP prompts until you restart. So `default_selected_permission` only
sets the starting point.
The accepted values are `always_allow_all_sessions`, `allow_command_always`,
`allow_once`, and `reject` (matching case-insensitively). When the key is unset
— or set to any unrecognized value — it falls back to `always_allow_all_sessions`.
The `allow_command_always` row is scoped to the specific action being approved
(command / tool / domain / edit-session), never a global allow-everything —
that is `always_allow_all_sessions`. Note that the per-command "Always allow"
rows appear only when `[ui] remember_tool_approvals = true` (default: false).
See [22-permissions-and-safety.md](22-permissions-and-safety.md).
The setting can also be overridden with the `GROK_DEFAULT_SELECTED_PERMISSION`
environment variable — handy for headless / agent test runs that shouldn't
mutate `config.toml`. Precedence: env var → `config.toml` →
`always_allow_all_sessions` (the default).
#### Vim Mode
The `vim_mode` setting under `[ui]` controls whether vim-style bindings are
active in the **scrollback** pane. It does not affect the input prompt.
| Value | Behavior |
|-------|----------|
| `false` (default) | Bare-letter and `Shift+letter` keys (`j`/`k`, `h`/`l`, `g`/`G`, `y`/`Y`, `o`/`O`, `r`, `x`, `e`/`E`, `H`/`L`, plus `i`) are suppressed in the scrollback. Pressing one of those letters focuses the prompt and types the character. Arrows, `Tab`, `Space`, `PageUp`/`PageDown`, and all `Ctrl+letter` shortcuts still navigate the scrollback. `Esc` is **not** a scrollback navigation key — it follows clear / rewind / mid-turn-swallow policy (see [Keyboard Shortcuts](03-keyboard-shortcuts.md#escape)). |
| `true` | All vim-style scrollback bindings are active, exactly as listed in [Keyboard Shortcuts](03-keyboard-shortcuts.md). |
Toggle `vim_mode` at runtime with `/vim-mode`, or from the settings pane
(`/settings` → **Vim scrollback navigation**). Grok writes the change to
`[ui] vim_mode` in `~/.grok/config.toml` immediately and applies it to every
future pager session — including new agents and subagents started in the same
process. There is no separate per-session override; whatever is in
`config.toml` is the source of truth on next launch.
`vim_mode` is independent of `simple_mode`: `vim_mode` controls scrollback
navigation, while `simple_mode` controls editing in the prompt.
#### Screen Mode
The `screen_mode` setting under `[ui]` is the **default render mode** for plain
`grok` launches. Configure it from `/settings` → **Default screen mode**
(restart required), or edit `config.toml` by hand. Both choices write
`config.toml`. CLI flags (`--minimal` / `--fullscreen`) and slash commands
(`/minimal` / `/fullscreen`) are session-scoped and do **not** write this key —
after a slash switch, the reverse command (`/fullscreen` ⇄ `/minimal`) returns
you for that session only.
| Value | Behavior |
|-------|----------|
| unset | Settings shows **Fullscreen**. At startup there is no sticky preference: legacy `pager.toml``[terminal] minimal` can still force minimal, and terminals that leak mouse reports (JediTerm/Windows) may auto-open minimal until you set an explicit value. Otherwise the alt-screen policy picks fullscreen vs inline. |
| `"fullscreen"` | Sticky non-minimal. Fullscreen-vs-inline still follows the alt-screen policy (`--no-alt-screen`, `[terminal] alt_screen`, terminal auto-detection). |
| `scroll_speed` | `1`–`100` (`50`) | Speed multiplier for both wheel and trackpad. `50` = 1.0x, `1` = 0.1x, `100` = 6.0x. |
| `scroll_mode` | `auto` \| `wheel` \| `trackpad` (`auto`) | Wheel-vs-trackpad detection is heuristic (terminal scroll events carry no magnitude); force one kind when auto-detection misreads your device — e.g. a wheel notch that jumps too far, or a trackpad that feels stepped. |
| `scroll_lines` | `1`–`10` (unset) | Lines per scroll tick, applied to **both** wheel and trackpad. While unset, each terminal's own profile applies (e.g. a conservative 1 line/event under tmux). Committing any value — even `3`, the number the settings pane displays — switches permanently to that explicit override. |
MCP servers can also be configured per-project in `.grok/config.toml`. Project-scoped config contributes `[mcp_servers]`, `[plugins]`, and `[permission]` rules; other sections load only from `~/.grok/config.toml`.
Priority for `[mcp_servers]` and `[plugins]`: `.grok/config.toml` (current dir) > `<repo-root>/.grok/config.toml` > `~/.grok/config.toml`. `[permission]` rules are not overridden by priority; they merge across all files with `deny` > `ask` > `allow` (see [22-permissions-and-safety.md](22-permissions-and-safety.md)).
### Memory
Persist knowledge across sessions (requires `--experimental-memory` or `GROK_MEMORY=1`).
```toml
[memory]
enabled = false # enable memory
[memory.session]
save_on_end = true # write metadata summary on session end
[memory.watcher]
enabled = true # watch memory files for external edits
[memory.search]
max_results = 6 # default number of results
min_score = 0.35 # minimum relevance score
[memory.initial_injection]
enabled = true # auto-inject memory on first turn
min_score = 0.0 # score threshold for first-turn injection
[memory.embedding]
model = "embedding-model" # embedding model name
dimensions = 1024 # vector dimensions
```
### Subagents
```toml
[subagents]
enabled = true
[subagents.toggle]
explore = true # enable/disable specific types
plan = false
[subagents.models]
explore = "grok-build" # route to different models
```
To pin the model a subagent uses, set its entry under `[subagents.models]`.
### Skills
```toml
[skills]
paths = ["~/my-team-skills"] # additional directories to scan
ignore = ["~/my-team-skills/wip"] # paths to exclude
disabled = ["wip-skill"] # skill names to keep listed but inactive
```
### Harness Compatibility
Control vendor compatibility for Cursor, Claude, and Codex. Every cell defaults to `true`; session cells remain staged/inert until the foreign-session scanner consumes them.
Session cells remain staged until a foreign-session scanner consumes them. Each tool requires both its `sessions` cell and corresponding `resume-claude`, `resume-codex`, or `resume-cursor` skill; a missing skill means zero foreign-session filesystem I/O.
```toml
[compat.cursor]
skills = true # scan ~/.cursor/skills/ and <cwd>/.cursor/skills/
For Claude and Cursor, `rules` and `agents` are independent: disabling named instruction files does not disable either the home or project rules directory, and disabling rules does not disable named files. Claude's `agents` cell gates home-level `~/.claude/` named files and project `<dir>/.claude/CLAUDE*.md`; generic top-level `Claude.md`, `CLAUDE.md`, and `CLAUDE.local.md` remain recognized. Project rule paths are scanned at every directory from the repo root to the current directory.
Each cell can be toggled via environment variable or `config.toml`. See the
environment-variables reference for the env var names. Resolution order:
env var > config.toml > default (on).
`grok inspect` reports cells that still need session-start resolution as
`?` until a value is available; cells with an explicit env or TOML value
use that value. Affected discovery entries report
`compatibilityStatus: "unresolved"` in JSON and `[compat unresolved]` in
human output.
### Plugins
```toml
[plugins]
paths = ["~/my-plugins/custom-tools"]
disabled = ["user/a1b2c3d4/noisy-plugin"]
```
### Hints
The `[hints]` table holds small persisted UI preferences — mostly "stop asking me" opt-outs. Grok writes these for you when you pick a "don't ask again" / "reset in config.toml" option in the TUI, but you can edit or remove them by hand. Deleting a key restores the default behavior.
`[hints]` is read from the **effective config merge** (same precedence as other settings): system managed → user `managed_config.toml` → user `config.toml` → user `requirements.toml` → system `requirements.toml`. Higher-priority layers override lower ones. The TUI only **writes** opt-outs to user `~/.grok/config.toml`.
```toml
[hints]
project_picker_disabled = false # skip the project-directory picker
memory_modal_fullscreen = false # remember the memory modal fullscreen state
| `project_picker_disabled` | bool | `false` | When `true`, skips the picker that asks you to choose a project directory on the first prompt when Grok is launched from a non-project directory (home, Desktop, Downloads, `/tmp`). Set automatically when you choose **"Don't ask me again"** in that picker. Teams can pin this in `managed_config.toml` or `requirements.toml` via `[hints] project_picker_disabled = true`. |
| `memory_modal_fullscreen` | bool | `false` | Remembers whether the memory modal was last opened fullscreen. |
| `new_session_worktree_mode` | string | `"never"` | Worktree prompt for `/new`: `ask` shows the popup, `always` creates a worktree, `never` skips it. |
| `fork_worktree_mode` | string | `"ask"` | Worktree prompt for `/fork`: `ask`, `always`, or `never`. |
### Notifications
Send terminal notifications when the agent finishes a turn or needs
| `sleep_prevention` | bool | `true` | Keep the display awake while the agent is working (macOS/Linux). |
| `progress_bar` | bool | `true` | Show a progress indicator in the terminal tab (OSC 9;4). |
| `title.enabled` | bool | `true` | Set the terminal title to reflect agent state. |
| `title.items` | array | (see above) | Items shown in the title bar. Options: `action-required`, `spinner`, `activity`, `session-name`, `cwd`, `model`, `turn-timer`, `grok`. |
#### Terminal Support Matrix
| Terminal | Auto Protocol | Focus Tracking | Progress Bar |
trace_upload = false # disable session/trace uploads (inherits the telemetry toggle when unset)
```
Set these only to point telemetry at your own infrastructure or to turn parts of it off. The built-in endpoint and credentials are managed by Grok; leave them unset to use the defaults.
The same `[telemetry]` table also configures the **external OpenTelemetry stream**, an independent opt-in (it does not require the telemetry toggle above) that ships a curated, content-free usage schema to your *own* OTLP collector. Collector auth is supplied via `OTEL_EXPORTER_OTLP_HEADERS` and is never stored on disk. See [Monitoring & Usage](24-monitoring-usage.md) for the full schema, env vars, and privacy model.
Some configuration can be set per-project by placing files in `.grok/` within your repository:
| File | What it configures |
|------|--------------------|
| `.grok/config.toml` | MCP servers, plugins, permission rules, and the `[mcp] max_output_bytes` tool-result cap (other sections load only from `~/.grok/config.toml`) |
Project-scoped MCP servers override global ones with the same name (full replacement, not merge).
---
## LSP Servers
Language servers power passive diagnostics and the optional `lsp` tool (see the [`lsp_tools`](#general-settings) feature flag). Server definitions are collected from three sources and merged by server name:
| Source | Location | Scope |
|--------|----------|-------|
| User | `~/.grok/lsp.json` | All projects |
| Project | `.grok/lsp.json` | Current repository |
| Plugin | A trusted plugin's `.lsp.json` file, or an inline `lspServers` block in its `plugin.json` | Wherever the plugin is enabled |
When the same server name is defined by more than one source, it is resolved in this order (highest priority first):
1.**Project** -- `.grok/lsp.json`
2.**User** -- `~/.grok/lsp.json`
3.**Plugins** -- file-based `.lsp.json`, then inline `lspServers`, in plugin load order
Project and user entries replace lower-priority ones with the same name. Plugin entries only add servers whose names are not already defined by a local file, so a local `lsp.json` always wins over a plugin. Plugin LSP servers load only after the plugin is trusted (see [Plugins](09-plugins.md)).