# i-have-adhd Multi-Platform Plugin Architecture: How One Rule Set Powers Claude Code, Codex, Pi, and OMP

> Discover the i-have-adhd multi-platform plugin architecture. Learn how one rule set powers Claude Code, Codex, Pi, and OMP using JSON manifests and a shared TypeScript extension.

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

---

**The `i-have-adhd` skill stores ADHD-friendly formatting rules in [`skills/i-have-adhd/SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/skills/i-have-adhd/SKILL.md) and deploys them across Claude Code, Codex, Pi, and OMP through thin JSON manifests, a shared TypeScript extension, and an optional always-on hook that prepends the rules to every system prompt.**

The `i-have-adhd` repository delivers a consistent, ADHD-friendly response style across multiple AI coding runtimes. Its multi-platform plugin architecture relies on a single source-of-truth skill file consumed by every supported platform. By separating the rule set from runtime-specific registration logic, the project guarantees identical behavior whether you invoke it in Claude Code, Codex, Pi, or OMP.

## Three-Layer Architecture Overview

The architecture is divided into three layers that are shared across all platforms:

- **Skill definition** – The human-readable rule set stored in [`skills/i-have-adhd/SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/skills/i-have-adhd/SKILL.md).
- **Runtime-specific manifest and glue code** – Platform files that register the skill and inject the rule set.
- **Always-on hook** – Optional flag-based injection that prepends rules to every system prompt.

This design means any edit to [`skills/i-have-adhd/SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/skills/i-have-adhd/SKILL.md) instantly propagates to every runtime without touching platform-specific code.

## Skill Definition: The Single Source of Truth

All platforms read their behavior rules from [`skills/i-have-adhd/SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/skills/i-have-adhd/SKILL.md). This file contains the complete ADHD-friendly rule set, including instructions to lead with the next action, number steps, and suppress tangents. Because every runtime loads this file directly—typically via `readFileSync(SKILL_PATH)`—a single change to the skill definition immediately updates behavior across Claude Code, Codex, Pi, and OMP.

## Runtime Manifests and Glue Code

### Claude Code and Codex JSON Manifests

Claude Code and Codex rely on minimal JSON manifests. The file [`.claude-plugin/plugin.json`](https://github.com/ayghri/i-have-adhd/blob/main/.claude-plugin/plugin.json) registers the plugin with the Claude Code runtime, while [`.codex-plugin/plugin.json`](https://github.com/ayghri/i-have-adhd/blob/main/.codex-plugin/plugin.json) does the same for Codex and adds UI metadata. Both manifests describe the plugin name, version, and description, and both declare the `skills/` directory so the runtime can locate [`SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/SKILL.md).

### Pi and OMP TypeScript Extension

Pi and OMP share a single TypeScript extension at [`extensions/i-have-adhd.ts`](https://github.com/ayghri/i-have-adhd/blob/main/extensions/i-have-adhd.ts). The [`package.json`](https://github.com/ayghri/i-have-adhd/blob/main/package.json) file declares this extension under the `pi` and `omp` fields:

```json
{
  "extensions": [
    "./extensions/i-have-adhd.ts"
  ]
}

```

The extension registers an `adhd` flag, an `i-have-adhd` command, and hooks into the session lifecycle via `session_start`, `session_tree`, and `session_compact`. During initialization, it loads the rule text with `readFileSync(SKILL_PATH)` and caches it for injection.

You can also interact with the extension programmatically:

```typescript
import { ExtensionAPI } from '@earendil-works/pi-coding-agent';

export default function (pi: ExtensionAPI) {
  pi.registerCommand('i-have-adhd', {
    description: 'Toggle ADHD-friendly output',
    handler: async (args, ctx) => {
      // same logic as the extension – toggle or force on/off
    },
  });
}

```

## Rule Injection and Session State

### On-Demand Toggle

Users can toggle ADHD-friendly formatting at runtime with the `/i-have-adhd` command. The extension maintains a session-wide state entry called `i-have-adhd-state`. When toggled on, the extension injects a custom-type message identified by `RULES_MESSAGE_TYPE` on the next turn, delivering the full rule set to the model.

You can also force a specific state:

```text
/i-have-adhd on
/i-have-adhd off

```

### Always-On Hook

For users who want the rules applied to every turn without running a command, the always-on hook checks for a hidden flag file. Claude Code looks for `~/.claude/.i-have-adhd-always`, while the OpenCode plugin uses `~/.config/opencode/.i-have-adhd-always`. When the flag exists, `hooks/always-on.mjs` or `.opencode/plugins/i-have-adhd.mjs` prepends the rule set to the system prompt automatically. The Pi/OMP extension consults its own `alwaysOnFlag` to enable the same behavior.

Create the flag to enable always-on mode:

```bash

# Claude Code

touch ~/.claude/.i-have-adhd-always

# OpenCode

touch ~/.config/opencode/.i-have-adhd-always

```

Remove the flag to disable it:

```bash
rm ~/.claude/.i-have-adhd-always
rm ~/.config/opencode/.i-have-adhd-always

```

### State Persistence

The extension saves the current mode as a custom entry (`i-have-adhd-state`) so it survives session reloads. When a new session starts, the `restoreState` routine reads the saved entry—or the always-on flag—and restores the UI status, displaying an `ADHD ON` badge if the skill is active.

## Cross-Runtime Compatibility

Because `i-have-adhd` uses the same skill file, the same rule-loading routine, and the same command name across every runtime, behavior is identical regardless of platform. The [`hooks/hooks.json`](https://github.com/ayghri/i-have-adhd/blob/main/hooks/hooks.json) file registers the always-on command specifically for Claude Code sessions, while the shared TypeScript extension and JSON manifests handle the rest. This unified approach eliminates drift between platforms and simplifies maintenance.

## Summary

- **[`skills/i-have-adhd/SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/skills/i-have-adhd/SKILL.md)** is the single source of truth for ADHD-friendly rules, loaded by all runtimes via `readFileSync(SKILL_PATH)`.
- **Claude Code** and **Codex** use lightweight JSON manifests ([`.claude-plugin/plugin.json`](https://github.com/ayghri/i-have-adhd/blob/main/.claude-plugin/plugin.json) and [`.codex-plugin/plugin.json`](https://github.com/ayghri/i-have-adhd/blob/main/.codex-plugin/plugin.json)) to register the skill.
- **Pi** and **OMP** rely on [`extensions/i-have-adhd.ts`](https://github.com/ayghri/i-have-adhd/blob/main/extensions/i-have-adhd.ts), registered in [`package.json`](https://github.com/ayghri/i-have-adhd/blob/main/package.json), to handle flags, commands, and lifecycle hooks.
- Users can toggle rules on demand with `/i-have-adhd` or enable always-on mode via a hidden flag file read by `hooks/always-on.mjs`.
- Session state is preserved through the `i-have-adhd-state` entry and restored by `restoreState` across reloads.

## Frequently Asked Questions

### How does the i-have-adhd plugin maintain a single source of truth across platforms?

The project stores its complete rule set in [`skills/i-have-adhd/SKILL.md`](https://github.com/ayghri/i-have-adhd/blob/main/skills/i-have-adhd/SKILL.md). Every runtime—Claude Code, Codex, Pi, and OMP—loads this file directly using `readFileSync(SKILL_PATH)`. When the skill file is updated, all platforms receive the new rules immediately without requiring individual code changes.

### What is the difference between on-demand and always-on rule injection?

On-demand injection requires the user to run `/i-have-adhd`, which sets the `i-have-adhd-state` flag and injects the rules as a `RULES_MESSAGE_TYPE` message on the next turn. Always-on injection relies on a hidden flag file—`~/.claude/.i-have-adhd-always` for Claude Code or `~/.config/opencode/.i-have-adhd-always` for OpenCode—read by `hooks/always-on.mjs` to prepend the rules to every system prompt automatically.

### Which file handles the Pi and OMP extension logic?

The TypeScript file [`extensions/i-have-adhd.ts`](https://github.com/ayghri/i-have-adhd/blob/main/extensions/i-have-adhd.ts) contains the shared extension logic for Pi and OMP. It is declared in [`package.json`](https://github.com/ayghri/i-have-adhd/blob/main/package.json) under the `pi` and `omp` fields and manages the `adhd` flag, the `i-have-adhd` command, and session lifecycle hooks such as `session_start`, `session_tree`, and `session_compact`.

### How is session state preserved when using i-have-adhd?

The extension persists the current mode as a custom `i-have-adhd-state` entry. When a new session begins, the `restoreState` function reads this entry—or checks the always-on flag file—and re-applies the previous configuration, including the `ADHD ON` UI badge.