Key Design Principles Behind the i-have-adhd Plugin: A Deep Dive into the Claude Code Extension

The i-have-adhd plugin is built around rule-driven output shaping, persistent session state, and minimal invasive context injection to deliver ADHD-friendly responses without overwhelming the model's context window.

The ayghri/i-have-adhd repository provides a lightweight extension for the Claude Code (Pi) runtime that modifies assistant behavior through declarative rules. Understanding the key design principles behind the i-have-adhd plugin reveals how stateful extensions can modify LLM output patterns through semantic markers rather than repetitive prompting.

Rule-Driven Output Shaping via SKILL.md

The plugin treats skills/i-have-adhd/SKILL.md as the single source of truth for all response behavior. This markdown file contains the canonical rule set defining ADHD-friendly formatting guidelines, stored separately from the executable code to allow non-developers to modify behavior.

The loadRules() function in extensions/i-have-adhd.ts reads this skill file at runtime, while stripFrontmatter removes YAML metadata before injecting the plain rules text into the model context. This separation ensures that response styling remains declarative and version-controlled independently of the extension logic.

Persistent Session State Management

State persistence prevents users from re-enabling the mode every session. The plugin implements getSavedState() to scan the session manager's branch for a custom entry of type i-have-adhd-state, retrieving the saved enabled/disabled flag from previous interactions.

When Claude Code initializes or rebuilds the conversation tree, restoreState() automatically applies the previously saved flag or defaults to the disabled state. This mechanism ensures continuity across session restarts without requiring explicit user commands each time.

Minimal Invasive Context Injection

To avoid flooding the model's context window with duplicate instructions, the extension employs syncContext() to check rulesAreInContext() before sending messages. This function utilizes latestMarkerIsActive() from extensions/context-compat.ts to walk the message list and determine whether an active i-have-adhd-rules marker or a disabling i-have-adhd-disabled marker already exists.

Rules are injected only once per session or when the mode toggles, significantly reducing token overhead compared to prepending instructions to every prompt.

Explicit User Control Mechanisms

Users retain full control through multiple interfaces. The pi.registerCommand("i-have-adhd", ...) handler in extensions/i-have-adhd.ts parses command arguments to flip the enabled flag, supporting explicit on/off states or simple toggling.

Natural language commands like "stop adhd mode" or "normal mode" trigger deactivation through the STOP_PHRASES set, allowing voice or conversational control. For permanent activation, users can create a .i-have-adhd-always flag file in the workspace, which the plugin detects on startup to override default state restoration.

UI Feedback and Safety Defaults

Visual confirmation appears through updateStatus(), which composes a "● ADHD ON" badge and pushes it to the UI via ctx.ui.setStatus(). This immediate feedback prevents confusion about whether the formatting rules are active.

Safety mechanisms ensure the plugin never forces rules when inappropriate. The latestMarkerIsActive() utility inspects the actual message history to verify current state before injecting or removing markers, respecting existing runtime hooks and preventing state desynchronization.

Extensible Architecture for Pi and OMP Runtimes

The iHaveAdhdExtension() function conforms to the generic ExtensionAPI and ExtensionContext interfaces, registering flags, commands, and event listeners against the standard Pi runtime API. This abstraction allows the identical codebase to function in both the Claude Code (Pi) environment and the OMP (Open-Code) runtime without modification.

By adhering to standard extension patterns—registering commands via pi.registerCommand() and accessing the session manager through ctx.sessionManager—the plugin demonstrates how specialized behavior modifications can integrate cleanly with assistant frameworks.

Summary

  • Single source of truth: All formatting rules live in skills/i-have-adhd/SKILL.md, loaded at runtime by loadRules() and cleaned by stripFrontmatter.
  • Stateful persistence: getSavedState() and restoreState() maintain the i-have-adhd-state entry across sessions.
  • Context efficiency: syncContext() leverages latestMarkerIsActive() to prevent duplicate rule injections.
  • Multiple control interfaces: Command-line toggles, natural language phrases via STOP_PHRASES, and the .i-have-adhd-always flag file provide flexible activation methods.
  • Runtime agnostic: The ExtensionAPI compliance ensures portability between Pi and OMP environments.

Frequently Asked Questions

How does the plugin prevent duplicate rule injections?

The syncContext() method checks rulesAreInContext() before sending messages, which calls latestMarkerIsActive() to traverse the message history. This function searches for existing i-have-adhd-rules or i-have-adhd-disabled markers, ensuring rules are injected only once per session or toggle event.

What file defines the ADHD-friendly response rules?

The canonical rule set resides in skills/i-have-adhd/SKILL.md. The loadRules() function reads this file and stripFrontmatter removes metadata before injection, keeping the behavior definition separate from the implementation code.

How does the plugin maintain state across Claude Code sessions?

The extension uses getSavedState() to retrieve a custom entry of type i-have-adhd-state from the session manager's branch, storing the enabled flag. On session start or tree rebuild, restoreState() reapplies this saved configuration automatically.

Can users permanently enable ADHD mode without typing commands?

Yes. Creating a .i-have-adhd-always flag file in the workspace directory signals the plugin to enable ADHD mode automatically on startup, overriding the default disabled state and bypassing the need for manual /i-have-adhd commands.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →