How the i-have-adhd Plugin Handles the Always-On Flag in OpenCode
The i-have-adhd plugin uses a filesystem flag file at ~/.config/opencode/.i-have-adhd-always to persistently inject ADHD-friendly rules into every model response via the experimental.chat.system.transform hook.
The ayghri/i-have-adhd repository provides an OpenCode plugin that mirrors the behavior of the original Claude Code integration, allowing users to keep ADHD-friendly formatting rules active across all chat turns. When the always-on flag is enabled, the plugin automatically prepends specific behavioral instructions to the system prompt on every interaction. This implementation relies on a simple file-based toggle mechanism that checks for the presence of a hidden flag file before injecting the ruleset.
Flag File Location and Detection
The plugin determines whether always-on mode is active by checking for the existence of a specific file in the user's OpenCode configuration directory. According to the source code in .opencode/plugins/i-have-adhd.mjs, the flag path is constructed using the XDG_CONFIG_HOME environment variable with a fallback to the standard ~/.config directory:
const flagPath = path.join(
process.env.XDG_CONFIG_HOME || path.join(os.homedir(), '.config'),
'opencode',
'.i-have-adhd-always'
);
Source: .opencode/plugins/i-have-adhd.mjs, lines 30-33
At the start of each chat turn, the transform hook checks this path using fs.existsSync. If the file is missing, the hook returns immediately without modifying the system prompt:
let on = false;
try { on = fs.existsSync(flagPath); } catch (e) {}
if (!on) return;
Source: .opencode/plugins/i-have-adhd.mjs, lines 60-63
Transform Hook and Ruleset Injection
When the flag file exists, the plugin activates the experimental.chat.system.transform hook to modify the system prompt before it reaches the model. The implementation follows three distinct phases: reading the ruleset, constructing a notification header, and appending the content to the system messages.
Reading the Skill Ruleset
The plugin references the rulesetBody() function to load the ADHD-friendly instructions from skills/i-have-adhd/SKILL.md. This function strips the YAML front-matter and trims trailing newlines, producing a clean text block identical to the one used by the traditional Claude Code hook.
Source: .opencode/plugins/i-have-adhd.mjs, lines 38-43
Injecting the Header and Rules
The plugin constructs a mandatory header that informs the model the ADHD mode is active and provides instructions for deactivation. It then appends this header and the ruleset body to the last system message, or creates a new system message if none exist:
const header = '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 ' + flagPath + ' to turn always-on off for good.';
const injected = header + '\n\n' + body;
// Append to system prompt
if (output.system.length > 0) {
output.system[output.system.length - 1] += '\n\n' + injected;
} else {
output.system.push(injected);
}
Source: .opencode/plugins/i-have-adhd.mjs, lines 67-78
Enabling and Disabling Always-On Mode
Users control the always-on behavior through filesystem operations and natural language commands. The plugin recognizes three distinct control methods:
- Enable always-on: Create the flag file to activate persistent injection across all sessions.
- Disable for current session: Tell the model "stop adhd mode" or "normal mode" to remove the injection temporarily (per the skill's persistence rules).
- Permanently disable: Delete the flag file to stop all future automatic injections.
Enable always-on using the command line:
touch ~/.config/opencode/.i-have-adhd-always
Permanently disable by removing the file:
rm ~/.config/opencode/.i-have-adhd-always
The same flag logic appears in the Claude Code reference implementation at hooks/always-on.mjs, which writes identical headers and rulesets to stdout when the flag exists.
Source: hooks/always-on.mjs, lines 15-23 and 36-40
Summary
- The always-on flag is a file-based toggle located at
~/.config/opencode/.i-have-adhd-always(or$XDG_CONFIG_HOME/opencode/.i-have-adhd-always). - The plugin checks for this file at the start of every chat turn using
fs.existsSyncin the transform hook. - When active, the plugin injects a header and the contents of
skills/i-have-adhd/SKILL.mdinto the system prompt via theexperimental.chat.system.transformhook. - Users can disable the mode permanently by deleting the flag file, or temporarily by telling the model to stop ADHD mode.
- The implementation mirrors the behavior found in the Claude Code
hooks/always-on.mjsreference implementation.
Frequently Asked Questions
Where is the always-on flag file stored?
The flag file is stored in the OpenCode configuration directory at ~/.config/opencode/.i-have-adhd-always by default. If the XDG_CONFIG_HOME environment variable is set, the plugin uses that path instead, appending /opencode/.i-have-adhd-always to the custom configuration root.
How do I temporarily disable ADHD mode without deleting the flag?
You can temporarily disable ADHD mode for the current session by telling the model "stop adhd mode" or "normal mode". According to the skill's persistence rules in SKILL.md, this command removes the injected text for that specific conversation without deleting the flag file, allowing you to preserve the always-on setting for future chats.
What hook does the plugin use to modify system prompts?
The plugin registers the experimental.chat.system.transform hook in .opencode/plugins/i-have-adhd.mjs. This hook intercepts the system prompt array before it is sent to the model, allowing the plugin to conditionally append the ADHD ruleset when the flag file is detected.
Does this work with Claude Code as well?
Yes, the repository includes a separate implementation for Claude Code in hooks/always-on.mjs that uses identical flag-detection logic. Both implementations check for the same flag file location and inject the same ruleset content, ensuring consistent behavior across OpenCode and Claude Code environments.
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 →