How i-have-adhd Injects System Prompts in OpenCode: Plugin Architecture Explained
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:
// 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.
The Always-On Flag File Mechanism
The transformer checks for persistent activation through a flag file. The isAlwaysOn function searches two locations:
// 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 for injection by:
- Reading the skill definition file
- Stripping YAML front-matter delimiters (
---) - 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
// 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
touch ~/.config/opencode/.i-have-adhd-always
Disable for current session only
echo "stop adhd mode"
Disable permanently
rm ~/.config/opencode/.i-have-adhd-always
Use without always-on flag
/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 injectionskills/i-have-adhd/SKILL.md– Canonical ADHD rule set processed byrulesetBody()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 normalizesSKILL.mdby 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. 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.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →