# How the Claude Code Always-On Mechanism Works in i-have-adhd

> Discover how Claude Code's always-on mechanism activates the ADHD-friendly skill automatically. Learn about flag file checks and SessionStart hooks in i-have-adhd.

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

---

**Claude Code's always-on mechanism automatically loads the ADHD-friendly skill at every session start by checking for a flag file and injecting rules from [`SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/SKILL.md) via a SessionStart hook.**

The `ayghri/i-have-adhd` repository implements a persistent, opt-in system that makes ADHD-friendly response formatting available without manual activation. This article explains the complete technical flow, from hook registration to rule injection, based on the actual source code implementation.

## How the SessionStart Hook Triggers the Mechanism

The always-on workflow begins with **[`hooks/hooks.json`](https://github.com/ayghri/i-have-adhd/blob/main/hooks/hooks.json)**, which declares a **SessionStart** hook that Claude executes at the beginning of every new session:

```json
{
  "hooks": {
    "SessionStart": "node hooks/always-on.mjs"
  }
}

```

When a Claude session initializes, this hook runs the Node module `hooks/always-on.mjs`. The mechanism is entirely automatic—no user interaction is required after the initial opt-in.

## The Always-On Module Execution Flow

The file **`hooks/always-on.mjs`** performs a five-step validation and injection process:

### 1. Resolve the Configuration Directory

The module first determines where Claude stores its configuration:

```javascript
const configDir = process.env.CLAUDE_CONFIG_DIR || path.join(os.homedir(), '.claude');

```

The `CLAUDE_CONFIG_DIR` environment variable takes precedence; otherwise, it defaults to `~/.claude`.

### 2. Verify the Opt-In Flag

The script checks for the existence of **`.i-have-adhd-always`** in the config directory:

```javascript
const flagPath = path.join(configDir, '.i-have-adhd-always');
if (!fs.existsSync(flagPath)) {
  process.exit(0);  // Silent exit—no modification to session
}

```

If the flag file is absent, the script exits immediately with status 0, ensuring **the hook never blocks session startup** for non-opted-in users.

### 3. Locate and Load the Skill Definition

With opt-in confirmed, the module resolves the skill path relative to its own location:

```javascript
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
const skillPath = path.resolve(scriptDir, '../skills/i-have-adhd/SKILL.md');

```

### 4. Process the Skill Content

The script reads [`SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/SKILL.md), strips its YAML front-matter, and cleans trailing newlines:

```javascript
const content = fs.readFileSync(skillPath, 'utf8');
const cleaned = content.replace(/^---[\s\S]*?---/, '').trim();

```

This extraction isolates the actual rule instructions from metadata headers.

### 5. Emit the Ruleset to stdout

Finally, the module outputs a prefixed message that Claude captures and injects:

```javascript
console.log(`[Injecting i-have-adhd skill rules...]\n${cleaned}`);

```

Claude receives this stdout output and applies the ruleset to every subsequent response in the session.

## Platform Fallback Implementations

The repository includes alternative implementations for environments where Node is unavailable.

### POSIX Shell Fallback: [`hooks/always-on.sh`](https://github.com/ayghri/i-have-adhd/blob/main/hooks/always-on.sh)

The bash script mirrors the Node logic using standard Unix utilities:

```bash
#!/bin/bash
set -e

# Determine config directory

CONFIG_DIR="${CLAUDE_CONFIG_DIR:-$HOME/.claude}"
FLAG_FILE="$CONFIG_DIR/.i-have-adhd-always"

# Check opt-in flag

[ -f "$FLAG_FILE" ] || exit 0

# Resolve skill path relative to script location

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
SKILL_FILE="$SCRIPT_DIR/../skills/i-have-adhd/SKILL.md"

# Strip front-matter with awk and output

awk '/^---$/{if(++c==2){p=1;next}}p' "$SKILL_FILE" | sed -e 's/^[[:space:]]*//; $a\' | xargs -0 printf '[Injecting i-have-adhd skill rules...]\n%s'

```

### PowerShell Version

A PowerShell implementation (`hooks/always-on.ps1`) provides equivalent functionality for Windows environments without Node.js.

## Managing the Always-On State

| Action | Command |
|--------|---------|
| **Enable** | `touch ~/.claude/.i-have-adhd-always` |
| **Disable permanently** | `rm ~/.claude/.i-have-adhd-always` |
| **Disable for current session only** | Send "stop adhd mode" to Claude |

The flag file is read on **every SessionStart event**, so changes take effect immediately across restarts without restarting Claude itself.

## Error Handling and Safety Guarantees

The always-on mechanism is designed to **never disrupt normal Claude operation**:

- All failure paths exit with status 0, preventing session blocking
- Missing skill files result in silent no-op behavior
- The `catch(()=>{})` pattern in debugging snippets suppresses error propagation
- No network calls or external dependencies are required after installation

## Summary

- The **always-on mechanism** is triggered by a `SessionStart` hook declared in [`hooks/hooks.json`](https://github.com/ayghri/i-have-adhd/blob/main/hooks/hooks.json).
- **`hooks/always-on.mjs`** checks for `.i-have-adhd-always` flag file before injecting rules.
- Rules are extracted from [`../skills/i-have-adhd/SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/../skills/i-have-adhd/SKILL.md) by stripping YAML front-matter.
- Output to stdout with `[Injecting i-have-adhd skill rules...]` prefix activates the behavior.
- POSIX and PowerShell fallbacks ensure cross-platform compatibility without Node.js.

## Frequently Asked Questions

### How do I enable Claude Code always-on mode for the ADHD skill?

Create an empty file named `.i-have-adhd-always` in your Claude config directory (typically `~/.claude`). The next Claude session will automatically activate the ADHD-friendly response style. No file content is required—the mere existence of the flag enables the mechanism.

### Why does the always-on script exit silently instead of showing errors?

The design prioritizes **non-blocking session startup**. By exiting with status 0 on any failure—including missing flag files, permission issues, or missing skill definitions—the hook ensures Claude sessions initialize normally regardless of `i-have-adhd` configuration state.

### Can I temporarily disable the always-on behavior without deleting the flag file?

Yes. Sending **"stop adhd mode"** to Claude disables rule injection for the remainder of that specific session. The flag file remains intact, so the skill will reactivate on the next session start. This provides granular control without permanent configuration changes.

### What happens if the skill file is moved or corrupted?

The Node script in `hooks/always-on.mjs` would encounter a file read error and exit with status 0, identical to the no-flag behavior. The POSIX fallback uses `set -e` for early exit on failures. In both cases, Claude operates normally without the ADHD modifications—no error messages appear to the user.