# Caveman Hook Scripts Explained: Activate, Statusline, and Mode-Tracker Triggers

> Learn about Caveman hook scripts activate statusline and mode-tracker. Discover how these scripts trigger automatically to enhance your coding workflow with Claude.

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

---

**Caveman provides three Claude Code hook scripts—[`caveman-activate.js`](https://github.com/JuliusBrussee/caveman/blob/main/caveman-activate.js), [`caveman-mode-tracker.js`](https://github.com/JuliusBrussee/caveman/blob/main/caveman-mode-tracker.js), and [`caveman-statusline.sh`](https://github.com/JuliusBrussee/caveman/blob/main/caveman-statusline.sh)—that trigger on `SessionStart`, `UserPromptSubmit`, and status-line UI refreshes respectively to inject rules, track mode changes, and display visual badges.**

The **Caveman** project by JuliusBrussee/caveman extends Claude Code with a primitive communication mode through a trio of hook scripts that intercept Claude's lifecycle events. These scripts enable automatic rule injection, real-time mode detection, and persistent UI indicators without manual configuration. Understanding the caveman hook scripts and their triggers is essential for customizing Claude Code's behavior across different intensity levels.

## What Are the Caveman Hook Scripts?

Caveman ships three core hook scripts located in `src/hooks/` that integrate with Claude Code's native hook system:

- **[`caveman-activate.js`](https://github.com/JuliusBrussee/caveman/blob/main/caveman-activate.js)** – Handles session initialization and rule injection
- **[`caveman-mode-tracker.js`](https://github.com/JuliusBrussee/caveman/blob/main/caveman-mode-tracker.js)** – Parses user prompts for mode activation commands
- **[`caveman-statusline.sh`](https://github.com/JuliusBrussee/caveman/blob/main/caveman-statusline.sh)** – Renders colored badges in Claude Code's status bar

Each script responds to a specific Claude Code event, creating a coordinated system that activates modes, persists state, and provides visual feedback.

## Hook Script Triggers and Execution Flow

### caveman-activate.js (SessionStart Trigger)

The **activate hook** fires on every new Claude Code session via the `SessionStart` event. Located at [`src/hooks/caveman-activate.js`](https://github.com/JuliusBrussee/caveman/blob/main/src/hooks/caveman-activate.js), this script performs four critical tasks when triggered:

1. Writes the current Caveman mode flag to `~/.claude/.caveman-active`
2. Emits the filtered Caveman ruleset based on selected intensity (lite, full, or ultra)
3. Applies any model-override settings configured for the current mode
4. Adds a status-line reminder if the user hasn't configured [`caveman-statusline.sh`](https://github.com/JuliusBrussee/caveman/blob/main/caveman-statusline.sh)

The hook executes with a 5-second timeout and runs immediately when opening a new Claude Code window or clicking *New Session*.

### caveman-mode-tracker.js (UserPromptSubmit Trigger)

The **mode-tracker hook** triggers on `UserPromptSubmit`, firing after each user prompt is submitted to Claude Code. Implemented in [`src/hooks/caveman-mode-tracker.js`](https://github.com/JuliusBrussee/caveman/blob/main/src/hooks/caveman-mode-tracker.js), this script inspects the incoming prompt JSON for activation patterns:

- **Explicit commands**: `/caveman`, `/caveman-lite`, `/caveman-ultra`, `/caveman-commit`
- **Natural language phrases**: "activate caveman", "talk like caveman", "be brief"
- **Deactivation phrases**: "stop caveman", "turn off caveman", "normal mode"

When detected, the script updates the `.caveman-active` flag and returns a JSON payload containing mode-specific context (e.g., "CAVEMAN MODE ACTIVE (ultra). Drop articles/filler/pleasantries/hedging"). Independent modes like `commit`, `review`, and `compress` bypass this hook and are handled elsewhere in the codebase.

### caveman-statusline.sh (Status-Line UI Hook)

The **statusline hook** runs continuously as a UI hook rather than responding to a specific Claude Code event. Located at [`src/hooks/caveman-statusline.sh`](https://github.com/JuliusBrussee/caveman/blob/main/src/hooks/caveman-statusline.sh), this shell script reads the mode flag file on every status bar redraw (effectively every keystroke) and outputs a colored badge.

The script prints ANSI-colored output such as:

```

[38;5;172m[CAVEMAN:ULTRA][0m

```

If [`caveman-stats.js`](https://github.com/JuliusBrussee/caveman/blob/main/caveman-stats.js) has generated a savings file, the script appends a suffix like "+ $12 saved" to the badge. The badge disappears automatically when the `.caveman-active` flag is removed.

## How the Hooks Are Installed

Running [`src/hooks/install.sh`](https://github.com/JuliusBrussee/caveman/blob/main/src/hooks/install.sh) idempotently configures Claude Code by copying the three scripts to `~/.claude/hooks/` and modifying `~/.claude/settings.json`:

```json
{
  "hooks": {
    "SessionStart": [
      {
        "command": "node \"~/.claude/hooks/caveman-activate.js\"",
        "timeout": 5000
      }
    ],
    "UserPromptSubmit": [
      {
        "command": "node \"~/.claude/hooks/caveman-mode-tracker.js\"",
        "timeout": 5000
      }
    ]
  },
  "statusLine": "bash \"~/.claude/hooks/caveman-statusline.sh\""
}

```

The installer checks existing settings to prevent duplicate entries and supports `--force` for clean reinstallation.

## Code Examples and Payloads

### SessionStart Payload

When [`caveman-activate.js`](https://github.com/JuliusBrussee/caveman/blob/main/caveman-activate.js) triggers on session start, it returns a structured payload to Claude Code:

```json
{
  "hookEventName": "SessionStart",
  "hookSpecificOutput": "CAVEMAN MODE ACTIVE — level: ultra\n\n…filtered rules for ultra intensity…"
}

```

This payload writes the flag file and streams the context-specific ruleset directly into the conversation context.

### UserPromptSubmit Context

After detecting a mode command, [`caveman-mode-tracker.js`](https://github.com/JuliusBrussee/caveman/blob/main/caveman-mode-tracker.js) emits additional context:

```json
{
  "hookEventName": "UserPromptSubmit",
  "additionalContext": "CAVEMAN MODE ACTIVE (ultra). Drop articles/filler/pleasantries/hedging. Fragments OK. Code/commits/security: write normal."
}

```

This context injection occurs only for active, non-independent modes (lite, full, ultra).

### Status-Line Badge Output

The status-line script generates terminal-formatted output for Claude Code's UI:

```bash
#!/bin/bash

# Reads ~/.claude/.caveman-active

# Outputs: [CAVEMAN:ULTRA] with color code 172 (orange)

echo -e "[38;5;172m[CAVEMAN:ULTRA][0m"

```

The script sources shared utilities from [`src/hooks/caveman-config.js`](https://github.com/JuliusBrussee/caveman/blob/main/src/hooks/caveman-config.js) for safe flag reading and validates mode strings before display.

## Summary

- **Three hook scripts** ([`caveman-activate.js`](https://github.com/JuliusBrussee/caveman/blob/main/caveman-activate.js), [`caveman-mode-tracker.js`](https://github.com/JuliusBrussee/caveman/blob/main/caveman-mode-tracker.js), [`caveman-statusline.sh`](https://github.com/JuliusBrussee/caveman/blob/main/caveman-statusline.sh)) provide the complete Caveman integration
- **SessionStart trigger** initializes modes and injects rulesets when Claude Code launches
- **UserPromptSubmit trigger** detects `/caveman` commands and natural language activation phrases in real-time
- **Status-line hook** displays persistent visual badges by reading the `.caveman-active` flag on every UI refresh
- **Installation** via [`src/hooks/install.sh`](https://github.com/JuliusBrussee/caveman/blob/main/src/hooks/install.sh) wires the scripts into `~/.claude/settings.json` with 5-second timeouts

## Frequently Asked Questions

### What triggers the caveman-activate.js script?

The script triggers on Claude Code's `SessionStart` event, which fires every time a user opens a new Claude Code window or initiates a fresh session. According to the source code in [`src/hooks/caveman-activate.js`](https://github.com/JuliusBrussee/caveman/blob/main/src/hooks/caveman-activate.js), this hook writes the mode flag file and emits the filtered ruleset before any user interaction occurs.

### How does caveman-mode-tracker.js detect mode changes?

The script parses the JSON payload of every `UserPromptSubmit` event to inspect the raw user input. It searches for explicit slash commands like `/caveman-ultra` or natural language phrases such as "talk like caveman" using pattern matching, then updates the `.caveman-active` flag accordingly.

### When does the status-line badge appear?

The badge appears immediately when the [`caveman-statusline.sh`](https://github.com/JuliusBrussee/caveman/blob/main/caveman-statusline.sh) script detects a valid mode flag at `~/.claude/.caveman-active`. Since the hook runs on every status bar redraw, the `[CAVEMAN]` or `[CAVEMAN:ULTRA]` badge updates in real-time as modes change, disappearing automatically when the flag is cleared.

### Where are the hook scripts installed?

The installer at [`src/hooks/install.sh`](https://github.com/JuliusBrussee/caveman/blob/main/src/hooks/install.sh) copies the three scripts to `~/.claude/hooks/` and registers them in Claude Code's [`settings.json`](https://github.com/JuliusBrussee/caveman/blob/main/settings.json) configuration file. This location ensures the hooks persist across Claude Code updates and remain available for all sessions.