Key Insights from Reading Caveman Repository Files: Architecture and Security Analysis

Reading the caveman repository's key files reveals a sophisticated security-focused architecture that compresses AI assistant outputs through hierarchical configuration resolution, symlink-safe state persistence, and real-time mode tracking across multiple IDE integrations.

The JuliusBrussee/caveman repository implements an agent-side skill designed to compress textual output from AI coding assistants while preserving code, commands, and error messages verbatim. By examining core files ranging from src/hooks/caveman-config.js to src/tools/caveman-init.js, developers can understand how the system balances user convenience with security hardening. This analysis explores the architectural insights embedded in the caveman repository's key implementation files.

Configuration Resolution and Security Architecture

The caveman repository's configuration system operates through a four-step precedence chain defined in src/hooks/caveman-config.js (lines 4–17). This resolver determines the active compression mode by checking sources in strict priority order: first the CAVEMAN_DEFAULT_MODE environment variable, then repository-local config files (.caveman/config.json or .caveman.json), followed by user-global configuration ($XDG_CONFIG_HOME/caveman/config.json), and finally falling back to the hard-coded default mode 'full'.

The module exports a whitelist of valid modes (VALID_MODES) including lite, full, ultra, and wenyan, alongside independent one-shot modes (commit, review, compress) used for temporary context switching.

Security considerations dominate the state persistence mechanism in src/hooks/caveman-config.js. The flag file .caveman-active resides in the user's config directory, with all I/O operations protected against symlink attacks through O_NOFOLLOW flags and strict size validation (MAX_FLAG_BYTES = 64).

The safeWriteFlag function implements atomic file creation by writing to a temporary file before renaming it into place (lines 81–92), preventing partial writes during crashes. Meanwhile, readFlag validates that the target is a regular file—not a symlink—and verifies content against VALID_MODES before returning (lines 11–22).

Runtime Mode Tracking and Reinforcement

The src/hooks/caveman-mode-tracker.js file contains the UserPromptSubmit hook that serves as the runtime engine for mode management. This component intercepts user commands to parse activation patterns and maintain state across conversation turns.

Command Parsing and State Updates

The hook detects explicit commands like /caveman, /caveman-commit, and natural-language activation patterns through the parseModeChange function (lines 34–66). Upon detecting a valid mode transition, the system calls safeWriteFlag to persist the selection and recordModeChange to append a timestamped entry to .caveman-mode-log.jsonl (lines 66–70, 75–78).

One-Shot Modes and Per-Turn Reinforcement

When users invoke independent one-shot modes such as commit or review, the system preserves the previous prose mode in .caveman-active.prev before activation, then restores it after the single turn completes (lines 76–90, 99–105).

The hook emits a reinforcement JSON payload on every LLM request (lines 93–100), injecting a system prompt reminder that instructs the model to maintain terse, compressed output consistent with the active caveman mode.

IDE Integration and Middleware

The repository extends its core functionality through IDE-specific plugins and MCP middleware while maintaining consistent security practices.

Opencode Plugin Implementation

The src/plugins/opencode/plugin.js file adapts the configuration and flag utilities for the Opencode IDE event model. The handleSessionCreated function (lines 75–82) writes the default mode flag on every session.created event, while message interception logic parses /caveman commands using the shared parseModeChange utility (lines 96–119).

The plugin transforms system prompts by appending the reinforcement line when the mode is active (lines 21–24), leveraging the same state management functions used by the generic agent implementations.

MCP Middleware Compression

The src/mcp-servers/caveman-shrink/index.js file implements MCP middleware that compresses tool descriptions for any server, extending the caveman compression logic beyond direct agent integration.

Practical Implementation Examples

Developers can interact with the caveman repository's systems programmatically or through configuration files.

Configure Default Mode via Environment

Set the default compression level for a repository by exporting the environment variable before starting your agent:

export CAVEMAN_DEFAULT_MODE=lite

Alternatively, create a repository-local configuration file:

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

The getDefaultMode resolver will prioritize these settings according to the precedence chain defined in src/hooks/caveman-config.js.

Query Active Mode Programmatically

Access the current mode safely without exposing symlink vulnerabilities:

const { readFlag, getConfigDir } = require('./src/hooks/caveman-config');
const path = require('path');

const flagPath = path.join(getConfigDir(), '.caveman-active');
const mode = readFlag(flagPath) || 'off';
console.log(`Caveman mode: ${mode}`);

The readFlag function validates file type and content before returning, protecting against malicious symlink attacks.

Simulate Opencode Plugin Initialization

Test the plugin initialization in a Node.js environment:

import { CavemanPlugin } from './src/plugins/opencode/plugin.js';

// Trigger session start behavior
await CavemanPlugin({});
// The plugin automatically writes the default mode flag via handleSessionCreated

Record Mode Transitions Manually

Log mode changes for statistical analysis using the recordModeChange utility:

const { recordModeChange, getConfigDir } = require('./src/hooks/caveman-config');
const path = require('path');

const claudeDir = path.join(getConfigDir(), '..'); // typically ~/.claude
recordModeChange(claudeDir, 'full');
// Appends timestamped JSON line to .caveman-mode-log.jsonl

This enables the /caveman-stats command functionality defined in src/hooks/caveman-stats.js.

Summary

  • Hierarchical configuration in src/hooks/caveman-config.js follows a strict four-step precedence chain from environment variables to hard-coded defaults.
  • Symlink-safe I/O protects state persistence through O_NOFOLLOW flags, atomic file writes, and 64-byte size caps (MAX_FLAG_BYTES).
  • Runtime mode tracking via src/hooks/caveman-mode-tracker.js parses commands, manages one-shot modes, and emits reinforcement prompts on every LLM request.
  • Cross-platform consistency is maintained through IDE-specific plugins like src/plugins/opencode/plugin.js that share core configuration and flag utilities.
  • Security-first design treats the .caveman-active flag file as a potential attack vector, validating file types and mode strings before every read operation.

Frequently Asked Questions

How does caveman prevent security vulnerabilities in state files?

The caveman repository prevents symlink attacks by using O_NOFOLLOW flags when opening the .caveman-active flag file and enforcing a maximum file size of 64 bytes (MAX_FLAG_BYTES). The readFlag function in src/hooks/caveman-config.js explicitly validates that the target is a regular file—not a symlink—and verifies content against the VALID_MODES whitelist before returning any data.

What is the configuration precedence order in caveman?

Configuration resolution follows a strict four-step precedence chain implemented in src/hooks/caveman-config.js: first checking the CAVEMAN_DEFAULT_MODE environment variable, then repository-local config files (.caveman/config.json or .caveman.json), followed by user-global configuration ($XDG_CONFIG_HOME/caveman/config.json), and finally defaulting to the hard-coded mode 'full'.

How do one-shot modes work in the caveman repository?

One-shot modes like commit, review, and compress temporarily override the active prose mode for a single turn. When triggered, the caveman-mode-tracker.js hook saves the current mode to .caveman-active.prev, activates the independent mode, executes the request, and automatically restores the previous mode from the backup file immediately after completion.

Which files should developers examine to understand caveman's IDE integration?

Developers should examine src/plugins/opencode/plugin.js to understand how the system adapts to IDE-specific event models while reusing core utilities. This file demonstrates session initialization (handleSessionCreated), message interception (handleChatMessage), and system prompt transformation, all leveraging the shared configuration and secure flag I/O functions from src/hooks/caveman-config.js.

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 →