# How i-have-adhd Injects System Prompts in OpenCode: Plugin Architecture Explained

> Discover how i-have-adhd injects ADHD-friendly system prompts into OpenCode. Learn about its innovative plugin architecture and experimental chat-system transformer.

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

---

**The i-have-adhd repository injects ADHD-friendly rules into every OpenCode system prompt using an experimental chat-system transformer that prepends a ruleset header when an always-on flag file is present.**

The `ayghri/i-have-adhd` project provides AI-assisted coding support tailored for developers with ADHD. According to the source code, the OpenCode integration works through a specialized plugin that modifies system prompts at the chat-transformer level, ensuring consistent rule application across entire sessions without manual intervention.

## How the OpenCode Plugin Registers Itself

The injection process begins with plugin registration in `.opencode/plugins/i-have-adhd.mjs`. When loaded, the `config` hook adds the `skills` directory to OpenCode's configuration:

```javascript
// Lines 45-53: Plugin registration adds skills path
config({ config }) {
  config.skills.push(join(__dirname, "..", "skills"));
}

```

This registration enables both the `/i-have-adhd` slash command and the `skill` tool to locate [`skills/i-have-adhd/SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/skills/i-have-adhd/SKILL.md).

## The Always-On Flag File Mechanism

The transformer checks for persistent activation through a flag file. The `isAlwaysOn` function searches two locations:

```javascript
// Lines 27-33: Flag file detection
const alwaysOnFlagfile = process.env.XDG_CONFIG_HOME
  ? join(process.env.XDG_CONFIG_HOME, "opencode", ".i-have-adhd-always")
  : join(homedir(), ".config", "opencode", ".i-have-adhd-always");

```

At lines 60-62, the plugin short-circuits injection if this file is absent—no flag, no system prompt modification.

## Loading and Formatting the Ruleset

The `rulesetBody` function (lines 35-43) prepares [`SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/SKILL.md) for injection by:

1. Reading the skill definition file
2. Stripping YAML front-matter delimiters (`---`)
3. Trimming trailing newlines

This normalization ensures the ruleset matches the format expected by other runtimes like Claude Code and Codex CLI.

## Constructing the System Prompt Header

Before injection, the plugin builds a descriptive header (lines 67-71):

```

ADHD MODE ACTIVE (always-on)
To disable for this session, say "stop adhd mode"
To disable permanently, run: rm ~/.config/opencode/.i-have-adhd-always

```

This header serves dual purposes: informing the model of active constraints and educating users on escape mechanisms.

## The Injection Logic

The actual system prompt modification occurs at lines 73-77. The transformer:

- Combines header + ruleset into `injected`
- Checks if a system prompt already exists
- Appends to the last system element, or creates a new one

```javascript
// Injection concatenation to existing or new system prompt
if (chat.system.length > 0) {
  chat.system[chat.system.length - 1].content += "\n\n" + injected;
} else {
  chat.system.push({ role: "system", content: injected });
}

```

This approach preserves existing system instructions while guaranteeing ADHD rules appear in every model context.

## Managing Always-On Mode

### Enable permanent injection

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

```

### Disable for current session only

```bash
echo "stop adhd mode"

```

### Disable permanently

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

```

### Use without always-on flag

```bash
/i-have-adhd

```

The slash command loads the skill for the remaining session without creating the persistent flag file.

## Key Implementation Files

- **`.opencode/plugins/i-have-adhd.mjs`** – Core transformer implementing chat-system injection
- **[`skills/i-have-adhd/SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/skills/i-have-adhd/SKILL.md)** – Canonical ADHD rule set processed by `rulesetBody()`
- **`hooks/always-on.mjs`** – Reference implementation that the OpenCode plugin mirrors

## Summary

- The i-have-adhd OpenCode plugin uses an **experimental chat-system transformer** to modify prompts
- **Flag file presence** (`~/.config/opencode/.i-have-adhd-always`) controls automatic injection
- The **`rulesetBody()` function** normalizes [`SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/SKILL.md) by removing YAML front-matter
- Injection **appends to existing system prompts** or creates new entries when absent
- Three activation modes exist: **always-on**, **session-only via slash command**, and **disabled**

## Frequently Asked Questions

### What is a chat-system transformer in OpenCode?

A chat-system transformer is an experimental OpenCode plugin hook that intercepts and modifies the chat context before it reaches the language model. The i-have-adhd plugin uses this mechanism to prepend its ruleset to every system prompt, similar to middleware in web frameworks. According to the source code, this runs on every turn when the always-on flag is active.

### Where does i-have-adhd store its rules for OpenCode?

The canonical rules live in [`skills/i-have-adhd/SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/skills/i-have-adhd/SKILL.md). The plugin's `config` hook adds the parent `skills` directory to OpenCode's configuration, allowing both the transformer and the `/i-have-adhd` command to locate and load this file. The `rulesetBody()` function handles format normalization at runtime.

### Can I use i-have-adhd without the always-on flag?

Yes. The `/i-have-adhd` slash command loads the skill for the remainder of the current session without creating the persistent flag file. This provides on-demand access without permanent system prompt modification. The source shows this is processed through the same `skills` registration path as the automatic mode.

### How do I completely remove i-have-adhd system prompt injection?

Delete the flag file with `rm ~/.config/opencode/.i-have-adhd-always` and restart OpenCode. The transformer checks for this file at lines 60-62; absence means no injection occurs. Existing conversations won't retroactively lose the rules, but new sessions will start clean.