# How Always-On Injection Works in i-have-ADHD Across Node, Shell, and PowerShell Harnesses

> Learn how i-have-adhd's always-on injection works differently across Node.js, shell, and PowerShell harnesses, loading rulesets via environment-specific session-start hooks when the opt-in flag file exists.

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

---

**The i-have-adhd repository implements always-on injection through environment-specific session-start hooks—Node.js modules for JavaScript-based runtimes, POSIX shell scripts for minimal containers, and PowerShell for Windows—each loading the ADHD ruleset when the opt-in flag file exists.**

The open-source project ayghri/i-have-adhd delivers consistent ADHD behavioral modifications across multiple AI coding assistants by adapting its **always-on injection** mechanism to the interpreter capabilities of each runtime harness. When a user opts in by creating the hidden flag file, the system selects the appropriate script to inject rules from [`skills/i-have-adhd/SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/skills/i-have-adhd/SKILL.md) without requiring Node.js on every platform.

## Node.js Harnesses: Claude Code, Codex, and npm-Based Runtimes

Claude Code, Codex, Pi, OMP, and OpenCode all utilize the same Node.js implementation for always-on injection, as they execute within JavaScript-capable environments.

### Hook Implementation in `always-on.mjs`

The primary hook resides in `hooks/always-on.mjs`. It imports Node's `fs`, `os`, and `path` modules to resolve the flag file at **`$CLAUDE_CONFIG_DIR/.i-have-adhd-always`** (defaulting to `~/.claude/.i-have-adhd-always`). When the flag exists, the script reads [`skills/i-have-adhd/SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/skills/i-have-adhd/SKILL.md), strips the leading YAML front-matter using regex, and writes the cleaned rules to `stdout`.

**Error resilience** is built into the Node implementation: any error—whether a missing flag file, missing skill file, or unexpected exception—triggers `process.exit(0)`, ensuring the session start never fails due to hook errors.

### Manifest-Driven Execution

Each Node-based harness references the hook through [`hooks/hooks.json`](https://github.com/ayghri/i-have-adhd/blob/main/hooks/hooks.json), which points to `always-on.mjs`. Claude Code's plugin runtime invokes the script directly with Node, enabling cross-platform support for macOS, Linux, and Windows without shell-specific translation. Pi and OMP load the identical module through their npm-based entry points and TypeScript extensions, while OpenCode reads [`opencode.json`](https://github.com/ayghri/i-have-adhd/blob/main/opencode.json) to execute the same script under Node.

## POSIX Shell Fallback for Minimal Environments

When Node.js is unavailable—as in minimal Linux containers or Git Bash on Windows—the harness falls back to [`hooks/always-on.sh`](https://github.com/ayghri/i-have-adhd/blob/main/hooks/always-on.sh).

### Pure POSIX Compatibility

This implementation uses **pure POSIX-compatible `sh`** syntax. It determines the script's location using the absolute path substitution via `$0` (provided by Claude Code in [`hooks.json`](https://github.com/ayghri/i-have-adhd/blob/main/hooks.json)) to compute `script_dir` and locate [`SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/SKILL.md) at [`../skills/i-have-adhd/SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/../skills/i-have-adhd/SKILL.md) relative to the hook's directory.

### Front-Matter Stripping with `awk`

The shell script implements a two-pass `awk` routine that removes leading `--- … ---` blocks only when a closing delimiter exists, mirroring the regex behavior of the Node version. It outputs a banner and the cleaned rule body using `printf` for consistent formatting across different shell implementations.

## PowerShell Fallback for Windows

For pure Windows environments without Node, `hooks/always-on.ps1` provides native PowerShell support.

The script follows the same logical flow as the Node and shell versions: it checks for the flag file, resolves the skill file path relative to **`$MyInvocation.MyCommand.Path`**, strips front-matter with a regular expression, and writes the rules to the console. This ensures **always-on injection** works in locked-down Windows environments where only PowerShell is available.

## Opt-In Flag and Cross-Platform Consistency

All harnesses share the identical opt-in mechanism. Create the hidden flag file to activate always-on mode:

```bash

# POSIX/Linux/macOS

mkdir -p "${HOME}/.claude"
touch "${HOME}/.claude/.i-have-adhd-always"

```

```powershell

# Windows PowerShell

$claudeDir = "$env:USERPROFILE\.claude"
New-Item -ItemType Directory -Path $claudeDir -Force
New-Item -ItemType File -Path "$claudeDir\.i-have-adhd-always" -Force

```

Once active, every session start invokes the appropriate hook, printing a banner like:

```text
ADHD MODE ACTIVE (always-on). The ruleset below applies to every response. "stop adhd mode" turns it off for this session; delete /home/user/.claude/.i-have-adhd-always to turn always-on off for good.

```

The system guarantees consistent rule content across platforms while allowing each runtime to use the most reliable interpreter available.

## Summary

- **Node.js harnesses** (Claude Code, Codex, Pi, OMP, OpenCode) use `hooks/always-on.mjs` with `process.exit(0)` error handling and YAML front-matter regex stripping.
- **POSIX shell fallback** ([`hooks/always-on.sh`](https://github.com/ayghri/i-have-adhd/blob/main/hooks/always-on.sh)) uses `$0` path resolution and two-pass `awk` front-matter removal for minimal environments.
- **PowerShell fallback** (`hooks/always-on.ps1`) uses `$MyInvocation.MyCommand.Path` for native Windows support without Node.
- All implementations read from [`skills/i-have-adhd/SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/skills/i-have-adhd/SKILL.md) and check for `$CLAUDE_CONFIG_DIR/.i-have-adhd-always` (default `~/.claude/.i-have-adhd-always`).
- The [`hooks/hooks.json`](https://github.com/ayghri/i-have-adhd/blob/main/hooks/hooks.json) manifest directs each harness to the appropriate script based on runtime capabilities.

## Frequently Asked Questions

### What file triggers always-on injection in i-have-adhd?

The hidden flag file `.i-have-adhd-always` within the Claude configuration directory triggers the injection. By default, the system looks for this file at `~/.claude/.i-have-adhd-always`, though it respects the `$CLAUDE_CONFIG_DIR` environment variable when set. All harness implementations check for this file's existence before loading rules from [`skills/i-have-adhd/SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/skills/i-have-adhd/SKILL.md).

### Why does the Node hook use `process.exit(0)` on errors?

The `process.exit(0)` call in `hooks/always-on.mjs` ensures that session startup never fails due to hook issues. If the flag file is missing, the skill file is unreadable, or an unexpected exception occurs, the hook exits cleanly with code 0, allowing the AI assistant to start normally without the ADHD ruleset rather than crashing the session.

### How does the POSIX shell version strip YAML front-matter without regex?

The [`hooks/always-on.sh`](https://github.com/ayghri/i-have-adhd/blob/main/hooks/always-on.sh) script uses a two-pass `awk` routine that tracks whether it is inside a front-matter block (delimited by `---`). It skips content between opening and closing delimiters only when both exist, effectively stripping the YAML header while preserving the markdown content—functionally equivalent to the regex approach in the Node version but compatible with POSIX `awk` implementations.

### Which harness implementations share the same hook code?

Claude Code, Codex, Pi, OMP, and OpenCode all execute the same `hooks/always-on.mjs` script because they run on Node.js-based platforms. The Pi and OMP extensions reference this module through their TypeScript entry points, while OpenCode loads it via [`opencode.json`](https://github.com/ayghri/i-have-adhd/blob/main/opencode.json), but the injection behavior and error handling remain identical across all JavaScript-capable runtimes.