# Understanding Hook Matcher Patterns in i-have-adhd hooks.json

> Learn how to use hook matcher patterns in i-have-adhd hooks.json to trigger actions with pipe-separated regex for specific commands during lifecycle events like SessionStart.

- Repository: [Ayoub Ghriss/i-have-adhd](https://github.com/ayghri/i-have-adhd)
- Tags: deep-dive
- Published: 2026-08-08

---

**The `matcher` field in [`hooks/hooks.json`](https://github.com/ayghri/i-have-adhd/blob/main/hooks/hooks.json) uses pipe-separated regular expressions to trigger hook actions when users type specific commands at lifecycle events like `SessionStart`.**

The *i-have-adhd* plugin implements a declarative hook system that responds to user commands through configurable patterns. By defining **hook matcher patterns** in [`hooks/hooks.json`](https://github.com/ayghri/i-have-adhd/blob/main/hooks/hooks.json), developers control which commands execute custom scripts during specific runtime events without modifying core plugin logic.

## Anatomy of the matcher Field

Each hook entry contains a **`matcher`** string that determines command eligibility. According to the source code in [`hooks/hooks.json`](https://github.com/ayghri/i-have-adhd/blob/main/hooks/hooks.json) (lines 5-6), this field accepts a pipe-separated list of keywords that the runtime evaluates as a regular expression.

The matcher supports three key characteristics:

- **OR Logic**: The pipe character (`|`) separates alternative commands, matching any single token in the list
- **Case Insensitivity**: The runtime normalizes all input to lowercase before testing against the pattern
- **Regex Extensibility**: Beyond simple tokens, the field accepts full regular expressions (e.g., `^task-.*$`) for complex pattern matching

In the built-in configuration, the `SessionStart` event uses the following matcher:

```json
{
  "matcher": "startup|resume|clear|compact"
}

```

This pattern triggers associated actions when users type any of the four commands at session initialization.

## Runtime Evaluation Logic

When the Cursor runtime processes a command, it executes a four-step evaluation chain:

1. **Normalization**: Converts the incoming command string to lowercase
2. **Event Lookup**: Identifies the current lifecycle context (e.g., `SessionStart`)
3. **Pattern Testing**: Evaluates the `matcher` regex against the normalized command
4. **Action Queuing**: Schedules the hook's defined actions (commands, scripts, or notifications) upon successful match

The evaluation occurs entirely within the runtime core; the plugin supplies only the declarative JSON configuration and referenced scripts.

## Extending Matcher Patterns for Custom Commands

To fire hooks for additional commands, extend the matcher string with new pipe-separated tokens. For example, to trigger the always-on script when users type `break` or `focus`:

```json
{
  "hooks": {
    "SessionStart": [
      {
        "matcher": "startup|resume|clear|compact|break|focus",
        "hooks": [
          {
            "type": "command",
            "command": "node",
            "args": ["${CLAUDE_PLUGIN_ROOT}/hooks/always-on.mjs"],
            "timeout": 5,
            "statusMessage": "Checking i-have-adhd always-on flag..."
          }
        ]
      }
    ]
  }
}

```

The runtime automatically recognizes the new tokens `break` and `focus` because the matcher treats the entire string as an "or" list. The associated script in `hooks/always-on.mjs` can then access these commands via `process.argv` to implement conditional logic:

```javascript
// hooks/always-on.mjs (simplified)
if (process.argv.includes('break')) {
  console.log('🧘‍♂️ Time for a break!');
}

```

## Key Implementation Files

The hook matcher system spans three primary files in the repository:

- **[`hooks/hooks.json`](https://github.com/ayghri/i-have-adhd/blob/main/hooks/hooks.json)**: Declares events, matcher strings, and action configurations
- **`hooks/always-on.mjs`**: Example script executed when matchers succeed; handles the plugin's "always-on" flag checking
- **[`extensions/i-have-adhd.ts`](https://github.com/ayghri/i-have-adhd/blob/main/extensions/i-have-adhd.ts)**: TypeScript entry point that registers the plugin and exposes the hook system to the runtime

## Summary

- **Hook matcher patterns** in [`hooks/hooks.json`](https://github.com/ayghri/i-have-adhd/blob/main/hooks/hooks.json) define which user commands trigger lifecycle actions using pipe-separated regex syntax
- Matching is case-insensitive and evaluates against normalized lowercase input
- The `SessionStart` event uses `"startup|resume|clear|compact"` to trigger the always-on status check
- Developers extend functionality by appending tokens to existing matcher strings or creating new hook entries
- The runtime handles all pattern evaluation, while the plugin provides declarative JSON and executable scripts

## Frequently Asked Questions

### What syntax does the matcher field support?

The `matcher` field accepts standard JavaScript regular expression syntax. For simple command lists, use pipe-separated tokens like `"cmd1|cmd2|cmd3"`. For advanced filtering, use full regex patterns such as `"^task-.*$"` to match any command starting with "task-".

### Is the matcher case-sensitive?

No. The runtime normalizes all incoming commands to lowercase before evaluating them against the matcher pattern. Define your patterns in lowercase to ensure consistent matching regardless of user input casing.

### How do I add a new command trigger to an existing hook?

Locate the relevant event in [`hooks/hooks.json`](https://github.com/ayghri/i-have-adhd/blob/main/hooks/hooks.json) (commonly `SessionStart`), find the `matcher` string, and append your new command separated by a pipe character. For example, change `"startup|resume"` to `"startup|resume|mycommand"`. The hook actions will now execute when users type "mycommand" during that event.

### Where does the matcher evaluation logic execute?

The pattern matching occurs within the Cursor/Claude runtime core, not in the plugin code itself. The runtime reads the `matcher` strings from [`hooks/hooks.json`](https://github.com/ayghri/i-have-adhd/blob/main/hooks/hooks.json) and tests them against normalized user input. If a match occurs, the runtime schedules the associated actions defined in the hook's `hooks` array, such as executing `hooks/always-on.mjs`.