# How to Implement Always-On Mode Across Different AI Platforms (Claude, Codex, OpenCode)

> Learn how to implement always-on mode for AI platforms like Claude, Codex, and OpenCode. This guide explains automatic ruleset injection for enhanced AI responses.

- Repository: [Ayoub Ghriss/i-have-adhd](https://github.com/ayghri/i-have-adhd)
- Tags: how-to-guide
- Published: 2026-08-26

---

**Always-on mode automatically injects the i-have-adhd ruleset into every model response by checking for platform-specific flag files and prepending the processed SKILL.md content to system prompts via Node.js hooks and plugins.**

The ayghri/i-have-adhd repository implements a cross-platform architecture to implement always-on mode across different AI platforms, ensuring consistent ADHD-friendly response formatting persists across Claude Code, GitHub Codex, and OpenCode sessions. This solution uses a unified ruleset source and platform-specific injection mechanisms to maintain behavior without manual prompting.

## Core Architecture Components

The always-on system relies on three primary components that work consistently across all supported platforms.

### The Opt-In Flag File

The **opt-in flag** is a zero-byte file that signals the user wants continuous ruleset application. The system checks for this file before injecting content:

- **Claude Code and Codex**: `~/.claude/.i-have-adhd-always` (path overridable via `CLAUDE_CONFIG_DIR` environment variable)
- **OpenCode**: `~/.config/opencode/.i-have-adhd-always`

These flag locations are defined in `hooks/always-on.mjs`, [`hooks/always-on.sh`](https://github.com/ayghri/i-have-adhd/blob/main/hooks/always-on.sh), and `.opencode/plugins/i-have-adhd.mjs` respectively.

### The Canonical Ruleset

The **canonical ruleset** resides in [`skills/i-have-adhd/SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/skills/i-have-adhd/SKILL.md) and serves as the single source of truth for ADHD-friendly response guidelines. All platform hooks read this file, remove any YAML front-matter using a standardized regular expression, and inject the remaining markdown content into the system prompt.

### Hook Scripts and Plugins

Three distinct implementations handle the injection logic:

- **Node.js Hook** (`hooks/always-on.mjs`): Primary implementation for Claude Code and Codex, invoked by the `SessionStart` hook
- **Shell Fallback** ([`hooks/always-on.sh`](https://github.com/ayghri/i-have-adhd/blob/main/hooks/always-on.sh)): POSIX-compatible fallback using `awk` for front-matter removal
- **PowerShell Fallback** (`hooks/always-on.ps1`): Windows-specific implementation for Claude Code/Codex
- **OpenCode Plugin** (`.opencode/plugins/i-have-adhd.mjs`): Per-turn injection system for OpenCode registered via [`opencode.json`](https://github.com/ayghri/i-have-adhd/blob/main/opencode.json)

## Platform-Specific Implementation Details

Each AI platform integrates the always-on functionality through different hook mechanisms, though all use identical ruleset processing logic.

### Claude Code and Codex SessionStart Hooks

For **Claude Code** and **Codex**, the system uses the `SessionStart` hook mechanism defined in [`hooks/hooks.json`](https://github.com/ayghri/i-have-adhd/blob/main/hooks/hooks.json). The Node.js script (`hooks/always-on.mjs`) runs at session initiation, checking for the flag file at `~/.claude/.i-have-adhd-always`. If present, it reads [`skills/i-have-adhd/SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/skills/i-have-adhd/SKILL.md), strips front-matter using the regex `/^---[^\S\r\n]*\r?\n[\s\S]*?\r?\n---[^\S\r\n]*(?:\r?\n|$)/`, and writes a header plus ruleset body to `stdout`. The platform automatically concatenates this output to the system prompt before the first model turn.

If Node.js is unavailable, the runtime falls back to [`hooks/always-on.sh`](https://github.com/ayghri/i-have-adhd/blob/main/hooks/always-on.sh) on Unix/macOS or `hooks/always-on.ps1` on Windows, which perform identical operations using native shell commands.

### OpenCode Per-Turn Plugin Injection

**OpenCode** implements always-on mode through the plugin system. The `.opencode/plugins/i-have-adhd.mjs` file registers an `experimental.chat.system.transform` hook that executes on every turn rather than only at session start. When the flag file exists at `~/.config/opencode/.i-have-adhd-always`, the plugin reads [`SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/SKILL.md), applies the same front-matter stripping regex, and injects the combined header and ruleset into `output.system`.

## Enabling Always-On Mode

Users opt-in by creating the appropriate flag file for their platform.

### For Claude Code and Codex

Create the flag file in your Claude configuration directory:

```bash
mkdir -p ~/.claude
touch ~/.claude/.i-have-adhd-always

```

If you have set the `CLAUDE_CONFIG_DIR` environment variable, create the file at `$CLAUDE_CONFIG_DIR/.i-have-adhd-always` instead.

### For OpenCode

Create the flag in the OpenCode configuration directory:

```bash
mkdir -p ~/.config/opencode
touch ~/.config/opencode/.i-have-adhd-always

```

Once created, the `.opencode/plugins/i-have-adhd.mjs` plugin will inject the ruleset on every subsequent turn.

## Disabling Always-On Mode

The system provides both temporary and permanent disable options.

### Temporary Session Disabling

To disable always-on mode for the current session only, type the following in your conversation:

```text
stop adhd mode

```

The injected header informs the model to respect the *Persistence* rule, disabling the ruleset for that specific session without removing the flag file.

### Permanent Disabling

To permanently disable always-on mode, delete the flag file:

```bash

# For Claude Code and Codex

rm ~/.claude/.i-have-adhd-always

# For OpenCode

rm ~/.config/opencode/.i-have-adhd-always

```

Removing this file prevents the hooks from injecting the ruleset in future sessions.

## Technical Implementation Details

The consistent behavior across platforms relies on standardized text processing.

### Front-Matter Stripping Logic

All three environments share exactly the same regular expression to remove YAML front-matter from [`SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/SKILL.md):

```javascript
/^---[^\S\r\n]*\r?\n[\s\S]*?\r?\n---[^\S\r\n]*(?:\r?\n|$)/

```

This regex matches the opening `---` delimiter, any content until the closing `---`, and trailing whitespace, ensuring only the substantive ruleset content remains for injection.

### Header Injection Format

The system prepends the following standardized header to the ruleset:

```text
ADHD MODE ACTIVE (always-on). The ruleset below applies to every response.
"stop adhd mode" or "normal mode" turns it off for this session;
delete <flag-path> to turn always-on off for good.

```

The `<flag-path>` placeholder displays the actual file path (e.g., `/home/user/.claude/.i-have-adhd-always`), providing users with context-specific instructions for disabling the feature.

## Summary

- **Always-on mode** uses flag files (`~/.claude/.i-have-adhd-always` or `~/.config/opencode/.i-have-adhd-always`) to signal opt-in status across Claude Code, Codex, and OpenCode platforms.
- The **canonical ruleset** in [`skills/i-have-adhd/SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/skills/i-have-adhd/SKILL.md) provides the single source of truth, with front-matter stripped using the regex `/^---[^\S\r\n]*\r?\n[\s\S]*?\r?\n---[^\S\r\n]*(?:\r?\n|$)/` before injection.
- **Claude Code and Codex** use `SessionStart` hooks (`hooks/always-on.mjs` with shell fallbacks) defined in [`hooks/hooks.json`](https://github.com/ayghri/i-have-adhd/blob/main/hooks/hooks.json) to inject content once at session start.
- **OpenCode** uses the `experimental.chat.system.transform` hook in `.opencode/plugins/i-have-adhd.mjs` to inject rules on every turn.
- Users disable the feature temporarily by typing "stop adhd mode" or permanently by deleting the flag file.

## Frequently Asked Questions

### How does the system handle the SKILL.md file differently between Claude Code and OpenCode?

Both platforms process [`skills/i-have-adhd/SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/skills/i-have-adhd/SKILL.md) identically using the same regular expression to strip YAML front-matter, but Claude Code and Codex inject the content once at session start via the `SessionStart` hook, while OpenCode injects it on every turn using the `experimental.chat.system.transform` hook. This ensures OpenCode maintains the ruleset even if the system prompt is modified mid-session.

### Can I use the always-on feature if Node.js is not installed?

Yes. While `hooks/always-on.mjs` is the primary implementation for Claude Code and Codex, the [`hooks/hooks.json`](https://github.com/ayghri/i-have-adhd/blob/main/hooks/hooks.json) configuration specifies fallback scripts. If Node.js is unavailable, the runtime automatically uses [`hooks/always-on.sh`](https://github.com/ayghri/i-have-adhd/blob/main/hooks/always-on.sh) on Unix/macOS or `hooks/always-on.ps1` on Windows, both of which implement the same flag-checking and front-matter stripping logic using native shell commands.

### What happens if I create the flag file while a session is already running?

For **Claude Code and Codex**, the `SessionStart` hook only executes when the session initializes, so creating the flag file mid-session will not activate always-on mode until you start a new session. For **OpenCode**, the `.opencode/plugins/i-have-adhd.mjs` plugin checks the flag file on every turn, so always-on mode activates immediately on the next interaction after you create `~/.config/opencode/.i-have-adhd-always`.

### Is the injected content identical across all three platforms?

Yes. According to the ayghri/i-have-adhd source code, all platforms use the same regex pattern and read from the same [`skills/i-have-adhd/SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/skills/i-have-adhd/SKILL.md) file, ensuring the ADHD-friendly formatting rules remain consistent whether you are using Claude Code, Codex, or OpenCode.