# Natural Language Activation and Deactivation in Caveman: How the Parser Works

> Discover how Caveman's regex-driven parser interprets natural language activation and deactivation commands, returning structured verdicts to control operational modes.

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

---

**Caveman interprets prose commands like "activate caveman" and "stop caveman" through a centralized regex-driven parser in [`src/hooks/caveman-parse.js`](https://github.com/JuliusBrussee/caveman/blob/main/src/hooks/caveman-parse.js) that returns structured verdicts to enable or disable operational modes.**

Caveman, an open-source utility developed by JuliusBrussee, provides a deterministic natural language interface for toggling its response modes without requiring strict slash-command syntax. The system relies on a single source-of-truth parser to examine raw user prompts and determine whether to activate, deactivate, or maintain the current configuration.

## The Central Parser Architecture

### Core Function and Location

All natural language processing flows through the `parseModeChange(prompt, options)` function exported from [`src/hooks/caveman-parse.js`](https://github.com/JuliusBrussee/caveman/blob/main/src/hooks/caveman-parse.js). This centralized approach ensures that both the CLI hook ([`caveman-mode-tracker.js`](https://github.com/JuliusBrussee/caveman/blob/main/caveman-mode-tracker.js)) and the Opencode plugin maintain identical behavior when interpreting user intent.

The function accepts two parameters:

- **`prompt`** – The raw text string entered by the user
- **`options`** – A configuration object controlling parser behavior and default modes

## Parse Verdicts and Mode States

The parser evaluates every input against deterministic regex patterns and returns one of three possible verdicts:

| Verdict | Meaning | Trigger Action |
|---------|---------|----------------|
| `{action: 'set', mode}` | **Activation** – Enable the specified mode | Caller enables Caveman with the identified mode (defaults to `full` for plain activation) |
| `{action: 'clear'}` | **Deactivation** – Turn off current mode | Caller disables Caveman entirely |
| `null` | No mode change | Continue with current configuration unchanged |

## Recognized Natural Language Patterns

### Activation Phrases

The parser recognizes multiple prose variants for engaging Caveman mode. According to the test suite in [`tests/test_caveman_parse.js`](https://github.com/JuliusBrussee/caveman/blob/main/tests/test_caveman_parse.js), the following inputs trigger mode activation:

- **"activate caveman"** – Returns `{action:'set', mode:'full'}` (line 136)
- **"be brief"** – Returns `{action:'set', mode:'full'}` (line 141)  
- **"talk like a caveman"** – Returns `{action:'set', mode:'full'}` (line 137)
- **"/caveman ultra"** – Returns `{action:'set', mode:'ultra'}` (line 48) for explicit mode targeting

### Deactivation Phrases

Similarly, the parser detects commands to exit Caveman mode:

- **"stop caveman"** – Returns `{action:'clear'}` (line 325)
- **"turn caveman mode off"** – Returns `{action:'clear'}` (line 154)
- **"normal mode"** – Returns `{action:'clear'}` (line 155)

## Input Sanitization and Edge Case Handling

### Quoted Span Removal

To prevent accidental triggering when users quote examples in documentation or bug reports, the parser implements `QUOTED_SPAN_REGEX` (lines 72-73) to remove content wrapped in double quotes (`"…"`) or backticks (`` `…` ``) before pattern matching begins.

### Punctuation Normalization

The `normalizeModeArg` function (lines 82-84) strips non-alphanumeric trailing characters from commands. This allows inputs like `/caveman ultra;` to correctly resolve to the `ultra` mode despite the trailing semicolon.

### Quote Unwrapping Behavior

When the entire prompt is wrapped in a single quote pair and the `unwrapQuotes` option is enabled, the parser removes the wrapping before evaluation. This prevents quoted commands from firing triggers unless explicitly intended.

## Configuration Options

### Disabling Natural Language Processing

By default, Caveman inspects all prose for activation triggers. Set `options.skipNaturalLanguage` to `true` to disable natural-language parsing and restrict input to explicit slash commands only. This is essential when processing command arguments not originating from direct user input.

### Default Mode Resolution

The parser relies on `options.getDefaultMode` to resolve fallback modes when activation phrases do not specify an explicit level (e.g., plain "activate caveman" defaults to `full`). This callback allows callers to inject project-level configuration or user preferences.

## Practical Implementation Examples

```javascript
const { parseModeChange } = require('./src/hooks/caveman-parse');
const defaultFull = { getDefaultMode: () => 'full' };

// Activation via natural language
let verdict = parseModeChange('activate caveman', defaultFull);
// → { action: 'set', mode: 'full' }
if (verdict?.action === 'set') {
  enableCaveman(verdict.mode);
}

// Deactivation via natural language
verdict = parseModeChange('stop caveman', defaultFull);
// → { action: 'clear' }
if (verdict?.action === 'clear') {
  disableCaveman();
}

// Skipping natural-language parsing for programmatic input
verdict = parseModeChange('/caveman ultra', {
  ...defaultFull,
  skipNaturalLanguage: true
});
// → { action: 'set', mode: 'ultra' }

```

## Summary

- **Centralized parsing** occurs in [`src/hooks/caveman-parse.js`](https://github.com/JuliusBrussee/caveman/blob/main/src/hooks/caveman-parse.js) via the `parseModeChange` function, ensuring consistency across CLI and plugin implementations.
- **Three verdict types** handle all state transitions: `set` for activation, `clear` for deactivation, and `null` for no change.
- **Flexible phrase recognition** supports variants like "be brief", "talk like a caveman", and "normal mode" alongside explicit slash commands.
- **Defensive parsing** removes quoted spans via `QUOTED_SPAN_REGEX` and normalizes punctuation through `normalizeModeArg` to prevent accidental triggers.
- **Optional suppression** via `skipNaturalLanguage` allows callers to disable prose parsing for automated or scripted inputs.

## Frequently Asked Questions

### How does Caveman prevent accidental activation when quoting commands in documentation?

The parser removes quoted spans using `QUOTED_SPAN_REGEX` (lines 72-73 of [`caveman-parse.js`](https://github.com/JuliusBrussee/caveman/blob/main/caveman-parse.js)) before evaluating triggers. This ensures that strings like `"activate caveman"` inside documentation examples do not toggle modes unintentionally.

### Can natural language parsing be disabled entirely?

Yes. Pass `skipNaturalLanguage: true` in the options object to `parseModeChange`. When enabled, the parser ignores prose-based patterns and processes only explicit slash commands like `/caveman ultra`.

### What happens if I include trailing punctuation in my command?

The `normalizeModeArg` function (lines 82-84) strips non-alphanumeric trailing characters automatically. Therefore, `/caveman ultra;` correctly activates ultra mode despite the semicolon.

### Where is the natural language parser tested?

Comprehensive unit tests covering both activation and deactivation phrases reside in [`tests/test_caveman_parse.js`](https://github.com/JuliusBrussee/caveman/blob/main/tests/test_caveman_parse.js), which validates line-specific behaviors for inputs like "talk like a caveman" (line 137) and "turn caveman mode off" (line 154).