# How Caveman's Hook Architecture Enables Auto-Activation on Claude Code

> Discover how Caveman's hook architecture auto-activates on Claude Code. Learn about session start hooks, intensity detection, and rule context injection for seamless integration.

- Repository: [Julius Brussee/caveman](https://github.com/JuliusBrussee/caveman)
- Tags: architecture
- Published: 2026-07-08

---

**Caveman achieves auto-activation on Claude Code by installing a SessionStart hook at [`src/hooks/caveman-activate.js`](https://github.com/JuliusBrussee/caveman/blob/main/src/hooks/caveman-activate.js) that detects intensity levels, writes a persistent flag file, and injects the full ruleset context every time Claude starts a new session.**

The **Caveman** coding assistant leverages Claude Code's native hook system to implement **auto-activation** without requiring manual startup commands or external dependencies. This architecture centers on a self-contained Node.js script that Claude executes automatically from the configuration directory, enabling seamless mode detection and context injection.

## The SessionStart Hook Entry Point

Claude Code automatically executes any script placed in `$CLAUDE_CONFIG_DIR/hooks/` at the start of every session. Caveman exploits this mechanism by installing [`src/hooks/caveman-activate.js`](https://github.com/JuliusBrussee/caveman/blob/main/src/hooks/caveman-activate.js) as the primary activation trigger.

The hook is **completely self-contained** – it does not rely on external binaries and gracefully degrades if any step fails, ensuring that Claude sessions never crash due to hook errors. This design allows the script to operate independently once copied to the correct directory.

## Detecting Intensity and Writing the Flag File

The activation process begins by determining the current Caveman intensity level. The hook calls `getDefaultMode()` to detect the active mode, then writes a flag file named `.caveman-active` into the user's Claude config directory.

This logic relies on helper utilities defined in [`src/hooks/caveman-config.js`](https://github.com/JuliusBrussee/caveman/blob/main/src/hooks/caveman-config.js), which exports `safeWriteFlag`, `readFlag`, and the `VALID_MODES` constant array. The flag file serves as the canonical indicator that Caveman is active for the current session, allowing other components to check status without re-executing detection logic.

## Injecting the Ruleset Context

After establishing the flag, the hook emits the full Caveman ruleset as hidden SessionStart context. The script locates [`SKILL.md`](https://github.com/JuliusBrussee/caveman/blob/main/SKILL.md) in several well-known directories, reads the file content, strips the YAML front-matter, and filters the intensity table to match only the currently active level.

According to the source code in [`src/hooks/caveman-activate.js`](https://github.com/JuliusBrussee/caveman/blob/main/src/hooks/caveman-activate.js) (lines 59-86), this parsing ensures that Claude receives only the relevant rules for the selected intensity, keeping the context window optimized while maintaining the full behavioral specification.

## Handling Off Mode and Graceful Degradation

When the mode is set to **"off"**, the hook removes the `.caveman-active` flag file and exits early (lines 27-33 in [`caveman-activate.js`](https://github.com/JuliusBrussee/caveman/blob/main/caveman-activate.js)). This ensures that **auto-activation can be disabled at runtime** without uninstalling the hook itself.

The script also detects missing status-line configuration and injects a friendly notification telling Claude how to add a status-line badge for the active mode (lines 42-67). This guidance appears only when needed, keeping the interface clean for users who have already configured their environment.

## Cross-Platform Reuse: The Opencode Pattern

The same hook architecture powers the Opencode integration in [`src/plugins/opencode/plugin.js`](https://github.com/JuliusBrussee/caveman/blob/main/src/plugins/opencode/plugin.js). This plugin watches for the `session.created` event, writes the flag file using the same mechanism, parses `/caveman` commands, and injects a reinforcement line into every system prompt.

This implementation demonstrates how the generic hook mechanism works across different AI coding environments, reusing the core logic from [`src/hooks/caveman-mode-tracker.js`](https://github.com/JuliusBrussee/caveman/blob/main/src/hooks/caveman-mode-tracker.js) to maintain consistent state management.

## Practical Examples

### Installing the Hook Manually

```bash

# Assume $HOME/.claude is the Claude config directory

mkdir -p $HOME/.claude/hooks
cp path/to/caveman/src/hooks/caveman-activate.js $HOME/.claude/hooks/

# The hook will now run automatically on every Claude Code SessionStart

```

### Toggling Caveman Mode from the CLI

```bash

# Toggle to "ultra" intensity (writes the flag file and emits the ruleset)

export CLAUDE_CONFIG_DIR=$HOME/.claude
node $HOME/.claude/hooks/caveman-activate.js   # runs the hook immediately

```

### Disabling Auto-Activation

```bash
export CLAUDE_CONFIG_DIR=$HOME/.claude

# Setting the mode to "off" removes the flag file; the hook will skip activation

echo "off" > $HOME/.claude/.caveman-mode   # or run the hook with OFF mode

node $HOME/.claude/hooks/caveman-activate.js

```

### Opencode Plugin Integration

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

// Opencode automatically calls the plugin on startup.
export default async function init(context) {
  const { event } = await CavemanPlugin(context);
  // The plugin will rewrite the flag on every `session.created` event.
}

```

## Summary

- **SessionStart automation**: Claude Code executes [`src/hooks/caveman-activate.js`](https://github.com/JuliusBrussee/caveman/blob/main/src/hooks/caveman-activate.js) automatically from `$CLAUDE_CONFIG_DIR/hooks/` at every session start.
- **State persistence**: The `.caveman-active` flag file tracks activation status across sessions using utilities from [`src/hooks/caveman-config.js`](https://github.com/JuliusBrussee/caveman/blob/main/src/hooks/caveman-config.js).
- **Context injection**: The hook reads [`SKILL.md`](https://github.com/JuliusBrussee/caveman/blob/main/SKILL.md), strips YAML front-matter, and filters rules by intensity level before injecting them into the session context.
- **Runtime control**: Setting the mode to "off" removes the flag file and disables auto-activation without uninstalling the hook.
- **Cross-platform reuse**: The same architecture powers the Opencode plugin in [`src/plugins/opencode/plugin.js`](https://github.com/JuliusBrussee/caveman/blob/main/src/plugins/opencode/plugin.js), demonstrating the pattern's portability.

## Frequently Asked Questions

### How do I install the Caveman hook for Claude Code?

Copy [`src/hooks/caveman-activate.js`](https://github.com/JuliusBrussee/caveman/blob/main/src/hooks/caveman-activate.js) to `$CLAUDE_CONFIG_DIR/hooks/` (typically `$HOME/.claude/hooks/`). Claude Code will execute this script automatically at the start of every session, enabling auto-activation without further configuration.

### What happens when I set the Caveman mode to "off"?

When the mode is "off", the hook removes the `.caveman-active` flag file from the Claude config directory and exits early. This disables the ruleset injection while keeping the hook installed for future activation, as implemented in lines 27-33 of [`src/hooks/caveman-activate.js`](https://github.com/JuliusBrussee/caveman/blob/main/src/hooks/caveman-activate.js).

### Where does Caveman store the activation status?

Caveman writes a flag file named `.caveman-active` to the user's Claude configuration directory. Helper functions in [`src/hooks/caveman-config.js`](https://github.com/JuliusBrussee/caveman/blob/main/src/hooks/caveman-config.js) manage this file through `safeWriteFlag` and `readFlag` utilities, ensuring atomic operations and validation against the `VALID_MODES` array.

### Can this hook architecture work with other AI coding assistants?

Yes. The architecture is reused in [`src/plugins/opencode/plugin.js`](https://github.com/JuliusBrussee/caveman/blob/main/src/plugins/opencode/plugin.js), which implements the same pattern for the Opencode IDE by watching `session.created` events and injecting reinforcement context. The core logic in [`src/hooks/caveman-mode-tracker.js`](https://github.com/JuliusBrussee/caveman/blob/main/src/hooks/caveman-mode-tracker.js) is platform-agnostic and can adapt to any environment that supports startup hooks or plugin events.