# How the Always-On Mechanism Works for OpenCode: A Deep Dive into Auto-Activated ADHD-Friendly Rules

> Discover how OpenCode's always-on mechanism auto-activates ADHD-friendly rules using a flag file and prompt injection at session startup for the i-have-adhd skill.

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

---

**OpenCode implements always-on activation for the i-have-adhd skill through a flag file that triggers automatic prompt injection at session startup.**

The `ayghri/i-have-adhd` repository provides an AI-assisted workflow designed for users with ADHD. For OpenCode users, the skill can remain permanently active without manual invocation. This article explains exactly how that mechanism works by examining the source code implementation.

---

## What the Always-On Flag Does

OpenCode checks for a sentinel file at `~/.config/opencode/.i-have-adhd-always`. When present, the plugin automatically loads the full ADHD ruleset into every conversation without user intervention.

This behavior mirrors Claude Code's `SessionStart` hook pattern. The flag eliminates friction for users who want the ADHD-friendly response format applied universally.

---

## Step-by-Step: How the Always-On Mechanism Executes

### Step 1: Flag Detection at Plugin Load

The `.opencode/plugins/i-have-adhd.mjs` file registers the skill and checks for the flag file during initialization.

```javascript
// Simplified from .opencode/plugins/i-have-adhd.mjs
const flagPath = path.join(os.homedir(), '.config', 'opencode', '.i-have-adhd-always');

if (fs.existsSync(flagPath)) {
  const rules = await fs.promises.readFile(
    path.join(root, 'skills', 'i-have-adhd', 'SKILL.md'), 
    'utf8'
  );
  systemPrompt += `\n${rules}`;
}

```

The plugin uses `fs.existsSync()` synchronously to check presence, then asynchronously reads [`skills/i-have-adhd/SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/skills/i-have-adhd/SKILL.md) to obtain the ruleset content.

### Step 2: Hook Registration via hooks.json

OpenCode discovers the always-on behavior through [`hooks/hooks.json`](https://github.com/ayghri/i-have-adhd/blob/main/hooks/hooks.json):

```json
{
  "command": "node -e \"(async()=>{const root=process.env.CLAUDE_PLUGIN_ROOT||process.env.PLUGIN_ROOT;if(root)await import(require('node:url').pathToFileURL(require('node:path').join(root,'hooks','always-on.mjs')).href)})().catch(()=>{})\"",
  "statusMessage": "Checking i-have-adhd always-on flag..."
}

```

This hook executes `hooks/always-on.mjs` whenever the plugin loads. The environment variable fallback (`CLAUDE_PLUGIN_ROOT` || `PLUGIN_ROOT`) ensures compatibility across runtime contexts.

### Step 3: Banner Display and Prompt Injection

The `hooks/always-on.mjs` script provides user feedback and confirms activation:

```javascript
// From hooks/always-on.mjs
console.log("ADHD MODE ACTIVE (always-on) …");
// Mirrors the injection logic from the main plugin

```

This Node.js implementation parallels the shell ([`always-on.sh`](https://github.com/ayghri/i-have-adhd/blob/main/always-on.sh)) and PowerShell (`always-on.ps1`) versions found in the same directory, maintaining cross-runtime consistency.

---

## Enabling and Disabling Always-On Mode

### Enable Permanent Always-On

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

```

Creating this empty file activates automatic loading for all subsequent OpenCode sessions.

### Disable for Current Session Only

Enter either command during conversation:

```bash
stop adhd mode

```

or

```bash
normal mode

```

These phrases trigger the plugin's session-level deactivation logic without affecting the persistent flag.

### Disable Permanently

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

```

Removing the flag file prevents automatic activation in future sessions while preserving the skill for manual invocation.

---

## Key Implementation Files

| File | Purpose |
|------|---------|
| `.opencode/plugins/i-have-adhd.mjs` | Core plugin logic; performs flag check and prompt augmentation |
| [`hooks/hooks.json`](https://github.com/ayghri/i-have-adhd/blob/main/hooks/hooks.json) | Declares the always-on hook for OpenCode's plugin system |
| `hooks/always-on.mjs` | Node.js runtime script for banner display and confirmation |
| [`skills/i-have-adhd/SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/skills/i-have-adhd/SKILL.md) | Source content containing all ADHD-friendly formatting rules |
| [`INSTALL.md`](https://github.com/ayghri/i-have-adhd/blob/main/INSTALL.md) | User-facing documentation for OpenCode setup |

The ruleset file ([`SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/SKILL.md)) contains the actual behavioral instructions—structured formatting, chunked responses, and prioritization cues—that OpenCode injects when always-on mode activates.

---

## Summary

- **always-on mechanism activation**: Create `~/.config/opencode/.i-have-adhd-always` to enable automatic loading
- **trigger point**: `.opencode/plugins/i-have-adhd.mjs` checks the flag at session start
- **injection target**: Full content of [`skills/i-have-adhd/SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/skills/i-have-adhd/SKILL.md) prepended to system prompt
- **temporary override**: `stop adhd mode` or `normal mode` disables for current session
- **permanent disablement**: Delete the flag file to stop automatic behavior

According to the `ayghri/i-have-adhd` source code, this architecture intentionally mirrors Claude Code's hook system while adapting to OpenCode's plugin conventions.

---

## Frequently Asked Questions

### What file exactly does OpenCode check for always-on mode?

OpenCode checks for `~/.config/opencode/.i-have-adhd-always`. The hardcoded path is constructed in `.opencode/plugins/i-have-adhd.mjs` using `path.join(os.homedir(), '.config', 'opencode', '.i-have-adhd-always')`.

### Does the always-on flag affect other Claude Code installations?

No. The flag path is OpenCode-specific. Claude Code uses its own `CLAUDE_PLUGIN_ROOT` environment variable and separate activation flow. The repository maintains distinct implementations for each platform in separate subdirectories.

### Can I customize which rules load in always-on mode?

Not without modifying the source. The plugin always loads the complete [`skills/i-have-adhd/SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/skills/i-have-adhd/SKILL.md) file. To use partial rules, you would need to fork the repository and edit the file read operation in `.opencode/plugins/i-have-adhd.mjs`.

### Why does the hook use such a complex Node.js command string?

The [`hooks/hooks.json`](https://github.com/ayghri/i-have-adhd/blob/main/hooks/hooks.json) command dynamically resolves the plugin root path across different installation contexts. It handles both `CLAUDE_PLUGIN_ROOT` (legacy compatibility) and `PLUGIN_ROOT` (current OpenCode), converts to file URLs for ES modules, and suppresses errors with `.catch(()=>{})` to prevent startup failures.