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

> Explore the i-have-adhd plugin's core design principles: rule-driven output, persistent state, and minimal context injection for ADHD-friendly Claude responses. Discover the ayghri/i-have-adhd repo.

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

---

**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`](https://github.com/ayghri/i-have-adhd/blob/main/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`](https://github.com/ayghri/i-have-adhd/blob/main/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`](https://github.com/ayghri/i-have-adhd/blob/main/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`](https://github.com/ayghri/i-have-adhd/blob/main/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`](https://github.com/ayghri/i-have-adhd/blob/main/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`](https://github.com/ayghri/i-have-adhd/blob/main/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.