Diffex uses JSON settings files with project settings overriding global settings.
| Location | Scope |
|---|---|
~/.diffex/agent/settings.json |
Global (all projects) |
.diffex/settings.json |
Project (current directory) |
Edit directly or use /settings for common options.
On interactive startup, Diffex asks before trusting a project folder that contains project-local settings, resources, or project .agents/skills and has no saved decision for the folder or a parent folder in ~/.diffex/agent/trust.json. Trusting a project allows Diffex to load .diffex/settings.json and .diffex resources, install missing project packages, and execute project extensions.
Non-interactive modes (-p, --mode json, and --mode rpc) do not show a trust prompt. Without an applicable saved trust decision, they use defaultProjectTrust from global settings: ask (default) and never ignore those project resources, while always trusts them. Pass --approve/-a or --no-approve/-na to override project trust for one run.
If no extension or saved decision applies, defaultProjectTrust controls the fallback behavior. Set it to "ask", "always", or "never" in ~/.diffex/agent/settings.json, or change it with /settings.
diffex config and package commands use the same project trust flow, except diffex update never prompts. Pass --approve to trust project-local settings for one command or --no-approve to ignore them.
Use /trust in interactive mode to save a project trust decision for future sessions, including trust for the immediate parent folder. It writes ~/.diffex/agent/trust.json only; the current session is not reloaded, so restart Diffex for changes to take effect.
Use /model or Ctrl+L to select a model, then choose from its supported thinking levels. Exact /model <id> matches and selecting the current model also open this screen. It is skipped when there is at most one supported level. Escape or Ctrl+C keeps the selected model and its current supported level. The thinking preference is shared across models and saved as defaultThinkingLevel, with existing model capability clamping.
| Setting | Type | Default | Description |
|---|---|---|---|
defaultProvider |
string | - | Default provider (e.g., "anthropic", "openai") |
defaultModel |
string | - | Default model ID |
defaultThinkingLevel |
string | - | "off", "minimal", "low", "medium", "high", "xhigh", "max" |
hideThinkingBlock |
boolean | false |
Hide thinking blocks in output |
showCacheMissNotices |
boolean | false |
Show transcript notices for significant prompt-cache misses |
thinkingBudgets |
object | - | Custom token budgets per thinking level |
{
"thinkingBudgets": {
"minimal": 1024,
"low": 4096,
"medium": 10240,
"high": 32768
}
}| Setting | Type | Default | Description |
|---|---|---|---|
theme |
string | "dark" |
Theme name ("dark", "light", or custom) |
externalEditor |
string | $VISUAL, then $EDITOR, then Notepad on Windows or nano elsewhere |
Command for Ctrl+G external editor; takes precedence over environment variables |
quietStartup |
boolean | false |
Hide startup header |
defaultProjectTrust |
string | "ask" |
Fallback project trust behavior: "ask", "always", or "never". Global setting only |
collapseChangelog |
boolean | false |
Show condensed changelog after updates |
enableProviderAttribution |
boolean | false |
Add optional attribution headers to OpenRouter, Cloudflare, and direct NVIDIA NIM requests |
enableAnalytics |
boolean | false |
Opt-in analytics data sharing. Currently only asked for during the experimental first-time setup (DIFFEX_EXPERIMENTAL=1) |
trackingId |
string | - | Analytics tracking identifier, generated when enableAnalytics is turned on |
doubleEscapeAction |
string | "tree" |
Action for double-escape: "tree", "fork", or "none" |
treeFilterMode |
string | "default" |
Default filter for /tree: "default", "no-tools", "user-only", "labeled-only", "all" |
editorPaddingX |
number | 0 |
Horizontal padding for input editor (0-3) |
outputPad |
number | 1 |
Horizontal padding for user messages, assistant messages, and thinking (0 or 1) |
autocompleteMaxVisible |
number | 5 |
Max visible items in autocomplete dropdown (3-20) |
showHardwareCursor |
boolean | false |
Show the terminal cursor while TUI positions it for IME support |
tuiMode |
string | "regular" |
Interactive TUI mode: "regular" or experimental "fullscreen". Changes from /settings apply immediately; --tui-mode overrides this setting at startup |
fullscreenScrollbar |
string | "auto" |
Fullscreen transcript scrollbar: "auto" shows it temporarily while scrolling, "always" reserves the rightmost column and keeps it visible, and "hidden" hides it. Has no effect in regular TUI mode |
For VS Code, include --wait so Diffex resumes after the editor exits:
{
"externalEditor": "code --wait"
}Diffex does not send install or update telemetry reports.
The former enableInstallTelemetry setting and DIFFEX_TELEMETRY variable are ignored.
Optional provider attribution defaults off so removing the old shared setting cannot re-enable headers for users who previously opted out.
Use enableProviderAttribution or DIFFEX_PROVIDER_ATTRIBUTION to control optional OpenRouter, Cloudflare, and direct NVIDIA NIM headers independently.
The environment variable takes precedence: 1/true/yes enables attribution; 0/false/no disables it.
This setting does not control update checks, OpenCode session headers, or explicitly configured request headers.
Set DIFFEX_SKIP_VERSION_CHECK=1 to disable automatic release checks against https://api.diffex.ai/api/latest-version.
Use --offline or DIFFEX_OFFLINE=1 to disable startup network operations, including update checks and package update checks.
| Setting | Type | Default | Description |
|---|---|---|---|
httpProxy |
string | - | HTTP proxy URL applied as HTTP_PROXY and HTTPS_PROXY. Global setting only. |
{
"httpProxy": "http://127.0.0.1:7890"
}| Setting | Type | Default | Description |
|---|---|---|---|
warnings.anthropicExtraUsage |
boolean | true |
Show a warning when Anthropic subscription auth may use paid extra usage |
{
"warnings": {
"anthropicExtraUsage": false
}
}| Setting | Type | Default | Description |
|---|---|---|---|
evolution.enabled |
boolean | true |
Global-only. Enables future invocation tracing and manual/background evolution controls. Disabling it does not unselect the active harness or remove active evolved skills. |
Already-running Diffex processes monitor this setting. A change made by another process is applied to their trace collectors and evolution workers without a restart.
Automatic work requires at least 400,000 provider-reported input and output tokens from unprocessed assistant messages, at least three eligible settled invocations, and a 10-minute cooldown after the previous automatic run. Each automatic run processes the oldest unprocessed evidence through the complete invocation that reaches or crosses the same 400,000-token trigger threshold. Only that final invocation may take the batch over the threshold; later invocations stay queued. Larger backlogs continue in threshold-sized batches after each cooldown, while partial batches wait for the threshold. Manual runs remain uncapped. The token total matches the response usage counter and excludes cache-read and cache-write usage. Evolution model calls may consume provider quota. See Harness Evolution.
| Setting | Type | Default | Description |
|---|---|---|---|
compaction.enabled |
boolean | true |
Enable auto-compaction |
compaction.reserveTokens |
number | 16384 |
Tokens reserved for LLM response |
compaction.keepRecentTokens |
number | 20000 |
Recent tokens to keep (not summarized) |
{
"compaction": {
"enabled": true,
"reserveTokens": 16384,
"keepRecentTokens": 20000
}
}| Setting | Type | Default | Description |
|---|---|---|---|
branchSummary.reserveTokens |
number | 16384 |
Tokens reserved for branch summarization |
branchSummary.skipPrompt |
boolean | false |
Skip "Summarize branch?" prompt on /tree navigation (defaults to no summary) |
| Setting | Type | Default | Description |
|---|---|---|---|
retry.enabled |
boolean | true |
Enable automatic agent-level retry on transient errors |
retry.maxRetries |
number | 3 |
Maximum agent-level retry attempts |
retry.baseDelayMs |
number | 2000 |
Base delay for agent-level exponential backoff (2s, 4s, 8s) |
retry.provider.timeoutMs |
number | SDK default | Provider/SDK request timeout in milliseconds |
retry.provider.maxRetries |
number | 0 |
Provider/SDK retry attempts |
retry.provider.maxRetryDelayMs |
number | 60000 |
Max server-requested delay before failing (60s) |
When a provider requests a retry delay longer than retry.provider.maxRetryDelayMs, the request fails immediately with an informative error instead of waiting silently. Set it to 0 to disable the limit.
Keep retry.provider.maxRetries at 0 unless provider-level retries are explicitly needed. Setting it above 0 can make SDK/provider retries handle out-of-usage-limit errors before Diffex sees them, which may block the agent until the provider quota resets in some circumstances.
{
"retry": {
"enabled": true,
"maxRetries": 3,
"baseDelayMs": 2000,
"provider": {
"timeoutMs": 3600000,
"maxRetries": 0,
"maxRetryDelayMs": 60000
}
}
}| Setting | Type | Default | Description |
|---|---|---|---|
steeringMode |
string | "one-at-a-time" |
How steering messages are sent: "all" or "one-at-a-time" |
followUpMode |
string | "one-at-a-time" |
How follow-up messages are sent: "all" or "one-at-a-time" |
transport |
string | "auto" |
Preferred transport for providers that support multiple transports: "sse", "websocket", "websocket-cached", or "auto" |
httpIdleTimeoutMs |
number | 300000 |
HTTP header/body idle timeout in milliseconds, also used by providers with explicit stream idle timeouts. Set to 0 to disable. |
websocketConnectTimeoutMs |
number | 15000 |
WebSocket connect/open handshake timeout in milliseconds for providers that support WebSocket transports. Set to 0 to disable. |
| Setting | Type | Default | Description |
|---|---|---|---|
terminal.showImages |
boolean | true |
Show images in terminal (if supported) |
terminal.imageWidthCells |
number | 60 |
Preferred inline image width in terminal cells |
terminal.clearOnShrink |
boolean | false |
Clear empty rows when content shrinks (can cause flicker) |
images.autoResize |
boolean | true |
Resize images to 2000x2000 max. Applies to @file attachments, read, and images returned by tools |
images.blockImages |
boolean | false |
Block all images from being sent to LLM |
| Setting | Type | Default | Description |
|---|---|---|---|
shellPath |
string | - | Custom shell path (e.g., for Cygwin on Windows); supports a leading ~ for the home directory |
shellCommandPrefix |
string | - | Prefix for every bash command (e.g., "shopt -s expand_aliases") |
npmCommand |
string[] | - | Command argv used for npm package lookup/install operations (e.g., ["mise", "exec", "node@20", "--", "npm"]) |
{
"npmCommand": ["mise", "exec", "node@20", "--", "npm"]
}npmCommand is used for all npm package-manager operations, including installs, uninstalls, and dependency installs inside git packages. User-scoped npm packages install under ~/.diffex/agent/npm/; project-scoped npm packages install under .diffex/npm/. Use argv-style entries exactly as the process should be launched. When npmCommand is configured, git package dependency installs use plain install to avoid npm-specific flags in wrappers or alternate package managers.
| Setting | Type | Default | Description |
|---|---|---|---|
sessionDir |
string | - | Directory where session files are stored. Accepts absolute or relative paths, plus ~. |
{ "sessionDir": ".diffex/sessions" }When multiple sources specify a session directory, precedence is --session-dir, DIFFEX_CODING_AGENT_SESSION_DIR, then sessionDir in settings.json.
| Setting | Type | Default | Description |
|---|---|---|---|
enabledModels |
string[] | - | Model patterns for Ctrl+P cycling (same format as --models CLI flag) |
{
"enabledModels": ["claude-*", "gpt-4o", "gemini-2*"]
}| Setting | Type | Default | Description |
|---|---|---|---|
markdown.codeBlockIndent |
string | " " |
Indentation for code blocks |
markdown.mermaid |
string | "streaming" |
Mermaid rendering mode: "off", "final", or "streaming" |
These settings define where to load extensions, skills, prompts, and themes from.
Use Installed skills in /settings to inspect global and workspace skill paths, sources, scopes, and enabled state. Toggle entries to persist global or project overrides, then use /reload to apply them to the current session. Evolved skills are read-only outside /evolve and /version.
Paths in ~/.diffex/agent/settings.json resolve relative to ~/.diffex/agent. Paths in .diffex/settings.json resolve relative to .diffex. Absolute paths and ~ are supported.
| Setting | Type | Default | Description |
|---|---|---|---|
packages |
array | [] |
npm/git packages to load resources from |
extensions |
string[] | [] |
Local extension file paths or directories |
skills |
string[] | [] |
Local skill file paths or directories |
prompts |
string[] | [] |
Local prompt template paths or directories |
themes |
string[] | [] |
Local theme file paths or directories |
Arrays support glob patterns and exclusions. Use !pattern to exclude. Use +path to force-include an exact path and -path to force-exclude an exact path.
String form loads all resources from a package:
{
"packages": ["@org/my-skills", "@org/my-extension"]
}Object form filters which resources to load:
{
"packages": [
{
"source": "@org/my-skills",
"skills": ["brave-search", "transcribe"],
"extensions": []
}
]
}See packages.md for package management details.
{
"defaultProvider": "anthropic",
"defaultModel": "claude-sonnet-4-20250514",
"defaultThinkingLevel": "medium",
"theme": "dark",
"compaction": {
"enabled": true,
"reserveTokens": 16384,
"keepRecentTokens": 20000
},
"retry": {
"enabled": true,
"maxRetries": 3
},
"enabledModels": ["claude-*", "gpt-4o"],
"warnings": {
"anthropicExtraUsage": true
},
"packages": ["@org/my-skills"]
}Project settings (.diffex/settings.json) override global settings. Nested objects are merged:
// ~/.diffex/agent/settings.json (global)
{
"theme": "dark",
"compaction": { "enabled": true, "reserveTokens": 16384 }
}
// .diffex/settings.json (project)
{
"compaction": { "reserveTokens": 8192 }
}
// Result
{
"theme": "dark",
"compaction": { "enabled": true, "reserveTokens": 8192 }
}