Architectural Design of the Multi-Platform Extension System in i-have-adhd
The i-have-adhd extension system uses a single-source-of-truth skill definition with runtime-specific manifests and pluggable injection strategies to support Claude Code, Codex, Pi, OMP, OpenCode, Qwen, Kimi, and Gemini.
This repository implements a unified "skill" architecture that governs ADHD-friendly response rules across multiple LLM-assistant runtimes. The multi-platform extension system separates concerns into skill source, runtime-specific plugins, context compatibility, always-on hooks, and state persistence—enabling consistent behavior without duplicating rule logic.
Core Architectural Concerns
The architectural design of the multi-platform extension system spans five distinct layers:
| Concern | Location | Purpose |
|---|---|---|
| Skill source | skills/i-have-adhd/SKILL.md |
Single source of truth for all ADHD-friendly rules |
| Runtime plugin manifests | .claude-plugin/, .codex-plugin/, qwen-extension.json, kimi.plugin.json, gemini-extension.json |
Platform-specific discovery and command registration |
| Pi/OMP extension logic | extensions/i-have-adhd.ts |
Toggle commands, state persistence, rule injection |
| Context compatibility | extensions/context-compat.ts |
Safe context inspection to prevent duplicate injections |
| Always-on activation | hooks/always-on.mjs, .opencode/plugins/i-have-adhd.mjs |
Automatic rule prepending via flag files |
Skill Source: The Single Source of Truth
All runtimes consume the same markdown file at skills/i-have-adhd/SKILL.md. Each implementation strips the front-matter before injection, ensuring rule updates propagate to every platform simultaneously.
This design eliminates version drift—change one file, affect all runtimes.
Runtime-Specific Extension Points
Claude Code and Codex
The .claude-plugin/plugin.json and .codex-plugin/plugin.json manifests register the /i-have-adhd slash command and expose the skill directory to the runtime's search path.
Pi and OMP
The extensions/i-have-adhd.ts file contains the full extension implementation for these runtimes:
// extensions/i-have-adhd.ts
// Core command handler that toggles mode and persists state
await pi.runCommand("/i-have-adhd on"); // enable rules
await pi.runCommand("/i-have-adhd off"); // disable rules
The file defines RULES_MESSAGE_TYPE for custom message injection and uses pi.appendEntry to save state to the session manager under the key i-have-adhd-state.
OpenCode
The .opencode/plugins/i-have-adhd.mjs plugin implements both command registration and a transformer for always-on mode:
// .opencode/plugins/i-have-adhd.mjs
// Config callback adds skills folder to search path
export function config(api) {
api.addSkillPath('./skills');
}
Context Compatibility Layer
Before injecting rules, the Pi/OMP extension verifies whether the rule set already exists in context. The extensions/context-compat.ts module provides two critical helpers:
contextMessages(sessionManager)— safely extracts message historylatestMarkerIsActive(messages, activeMarker, disabledMarker)— detects rule presence
import { contextMessages, latestMarkerIsActive } from "./context-compat";
function rulesAreInContext(ctx) {
const msgs = contextMessages(ctx.sessionManager);
return latestMarkerIsActive(msgs, "i-have-adhd-rules", "i-have-adhd-disabled");
}
This prevents duplicate rule injection and enables clean toggling between states.
Always-On Activation Mechanism
Users can opt into persistent rule application through flag files. When present, hooks automatically prepend the rule set to every system prompt.
Claude Code / Codex
# Create flag file in Claude's config directory
touch ~/.claude/.i-have-adhd-always
The hooks/always-on.mjs script checks for this file at session start:
// hooks/always-on.mjs
const flagPath = path.join(os.homedir(), '.claude', '.i-have-adhd-always');
if (fs.existsSync(flagPath)) {
// Prepend SKILL.md content to system prompt
}
OpenCode
# Create flag file in OpenCode's config directory
touch ~/.config/opencode/.i-have-adhd-always
The OpenCode transformer in .opencode/plugins/i-have-adhd.mjs performs the same check on every turn.
State Persistence and Restoration
For Pi and OMP, session state survives across restarts. The extension:
- Saves toggle state via
pi.appendEntry('i-have-adhd-state', payload) - Restores on session start via
getSavedState()inextensions/i-have-adhd.ts - Re-applies the appropriate mode (enabled, disabled, or always-on)
Claude Code and Codex rely on filesystem flags rather than session storage, matching their hook-based architecture.
Execution Flow: How Pieces Fit Together
- Discovery — Runtime loads its manifest and adds
skills/to the search path - Command registration —
/i-have-adhdbecomes available as a slash command - Rule injection — Two paths exist:
- On-demand: User runs command →
loadRules()strips front-matter → injectsRULES_MESSAGE_TYPE - Always-on: Flag file exists → hook/transformer prepends rules automatically
- On-demand: User runs command →
- Context sync —
rulesAreInContext()checks for existing markers before injection - State restoration — Previous session state re-applied on startup
Summary
- Single source of truth:
skills/i-have-adhd/SKILL.mdgoverns all platforms - Pluggable runtime adapters: Each LLM assistant uses its own manifest and injection strategy
- Context-aware injection:
context-compat.tsprevents duplicate rule application - Filesystem-based always-on: Flag files enable persistent activation without code changes
- Session state persistence: Pi/OMP store toggle state; Claude/Codex use flags exclusively
Frequently Asked Questions
How does the system prevent the same rules from being injected twice?
The Pi/OMP extension calls rulesAreInContext() before injection, which uses latestMarkerIsActive() from extensions/context-compat.ts to scan message history for "i-have-adhd-rules" or "i-have-adhd-disabled" markers. If found, injection is skipped.
What file enables always-on mode for Claude Code?
Create ~/.claude/.i-have-adhd-always. The hooks/always-on.mjs script detects this file at session start and prepends the full rule set to every system prompt automatically.
How is state persisted in the Pi/OMP runtime?
The extension calls pi.appendEntry('i-have-adhd-state', payload) in extensions/i-have-adhd.ts. The getSavedState() function retrieves this entry on session startup, enabling mode restoration across restarts.
Which runtimes are currently supported by this extension system?
According to the repository source code, the system supports Claude Code, Codex, Pi, OMP, OpenCode, Qwen, Kimi, and Gemini through their respective manifest files and extension hooks.
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 →