How to Configure the Default Caveman Mode: Complete Configuration Guide

Caveman determines its default operating mode through a deterministic four-step resolution chain, prioritizing environment variables first, then repository-local configs, followed by user-level settings, and finally falling back to the built-in default of 'full'.

The JuliusBrussee/caveman repository implements a hierarchical configuration system that allows developers to define default behavior at environment, project, or global levels. Understanding how to configure the default Caveman mode requires familiarity with the resolution priority implemented in the core configuration resolver.

The Caveman Mode Resolution Chain

Caveman resolves the default mode using a cascading priority system defined in src/hooks/caveman-config.js. The getDefaultMode(startDir) function (lines 96-115) implements a deterministic lookup that stops at the first valid configuration found:

  1. Environment variable (CAVEMAN_DEFAULT_MODE) — inspected directly in process.env
  2. Repository-local config — searches upward from current working directory for .caveman/config.json or .caveman.json
  3. User-level config — checks $XDG_CONFIG_HOME/caveman/config.json, then ~/.config/caveman/config.json, then %APPDATA%\caveman\config.json
  4. Built-in default — returns the literal string 'full'

The findRepoConfigPath() function (lines 45-70) handles repository-local discovery by walking upward from the current working directory for a maximum of 64 levels, ignoring symlinks for security. For user-level resolution, getConfigDir() (lines 28-38) implements XDG Base Directory specification with Windows fallbacks.

Only values present in VALID_MODES are accepted. If a source contains an invalid or missing defaultMode field, Caveman silently proceeds to the next resolution step.

Method 1: Environment Variable Configuration

Setting the CAVEMAN_DEFAULT_MODE environment variable provides the highest priority configuration, overriding all file-based settings. This method is ideal for CI/CD pipelines or temporary mode switching.


# Bash / Zsh - Persistent for session

export CAVEMAN_DEFAULT_MODE=lite

# Single command execution

CAVEMAN_DEFAULT_MODE=wenyan-full caveman <arguments>

Method 2: Repository-Level Configuration

For project-specific defaults that should be committed with your codebase, create a configuration file at the repository root. The resolver accepts either .caveman/config.json or .caveman.json located in the current working directory or any ancestor directory.

// .caveman/config.json
{
  "defaultMode": "commit"
}

Place this file in your project root to ensure all team members use the same default mode when working in this repository. The findRepoConfigPath() function automatically discovers this file by traversing up to 64 parent directories.

Method 3: User-Level Global Configuration

To set a personal default across all projects, create a configuration file in your user's configuration directory. Caveman checks these locations in order:

  • $XDG_CONFIG_HOME/caveman/config.json (Linux/macOS XDG standard)
  • ~/.config/caveman/config.json (Linux/macOS fallback)
  • %APPDATA%\caveman\config.json (Windows)

Linux / macOS setup:

mkdir -p ~/.config/caveman
cat > ~/.config/caveman/config.json <<'EOF'
{
  "defaultMode": "ultra"
}
EOF

Windows PowerShell setup:

$dir = "$env:APPDATA\caveman"
New-Item -ItemType Directory -Force -Path $dir
Set-Content -Path "$dir\config.json" -Value '{ "defaultMode": "ultra" }'

Valid Mode Options

The configuration must specify a mode present in the VALID_MODES array. Acceptable values include:

  • off
  • lite
  • full (built-in default)
  • ultra
  • wenyan-lite
  • wenyan
  • wenyan-full
  • wenyan-ultra
  • commit
  • review
  • compress

Invalid values trigger silent fallback to the next resolution level.

Programmatic Access

You can read the resolved mode programmatically using the same resolver that Caveman uses internally:

const { getDefaultMode } = require('./src/hooks/caveman-config');
const mode = getDefaultMode(); // Uses process.cwd() by default
console.log('Effective Caveman mode:', mode);

This returns the canonical mode string according to the four-step resolution chain described above.

Summary

  • Four-step priority: Environment variables override repository configs, which override user configs, which override the built-in default ('full')
  • Repository config: Create .caveman/config.json or .caveman.json in your project root (found via upward traversal)
  • User config: Place config.json in $XDG_CONFIG_HOME/caveman/ (Linux/macOS) or %APPDATA%\caveman\ (Windows)
  • Implementation: Core logic resides in src/hooks/caveman-config.js, specifically getDefaultMode(), findRepoConfigPath(), and getConfigDir()
  • Validation: Only modes in VALID_MODES are accepted; invalid entries trigger silent fallback

Frequently Asked Questions

What happens if I specify an invalid mode in my configuration file?

If the defaultMode value in any configuration source is not present in the VALID_MODES array, Caveman silently ignores that configuration and proceeds to the next step in the resolution chain. For example, if your repository config contains an invalid mode, Caveman will fall back to your user-level config or the built-in default.

No. The findRepoConfigPath() function explicitly ignores symlinks when walking the directory tree from the current working directory. This security measure prevents traversal attacks and ensures configuration integrity. You must place actual files at the specified locations.

How do I temporarily override a project-specific default for a single command?

Set the CAVEMAN_DEFAULT_MODE environment variable immediately before the command. Because environment variables have the highest priority in the resolution chain, they override repository-local and user-level configurations. For example: CAVEMAN_DEFAULT_MODE=off caveman status.

Where does Caveman store the configuration directory on Windows?

On Windows systems, Caveman uses %APPDATA%\caveman\config.json as the user-level configuration path. The getConfigDir() function in src/hooks/caveman-config.js implements this fallback after checking XDG-compliant paths, ensuring cross-platform compatibility for global settings.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →