How the i-have-adhd Extension is Registered for Pi and OMP: A Technical Deep Dive

The i-have-adhd extension registers for Pi and OMP runtimes by loading rule files and configuration, then exposing a CLI flag (--adhd), a slash command (/i-have-adhd), and lifecycle hooks that inject or retract ADHD guidance rules into the model context based on session state.

The ayghri/i-have-adhd repository provides a toggleable ADHD-friendly mode for AI coding assistants. Understanding how the i-have-adhd extension is registered for Pi and OMP reveals a sophisticated pattern for runtime extension management, state persistence, and dynamic context manipulation.

Extension Architecture and Registration Overview

Both Pi and OMP (Open-Multi-Platform) runtimes share an identical registration implementation because they consume the same ExtensionAPI contract. The registration process declared in extensions/i-have-adhd.ts initializes the extension by loading static resources, registering user interface elements, and binding event listeners to session lifecycle hooks.

The extension operates as a stateful middleware that intercepts session events to maintain a consistent ADHD-friendly context across conversation turns.

Step-by-Step Registration Process

Loading ADHD Rules and Configuration

Registration begins by loading the core rule set and optional user preferences. The loadRules() function reads skills/i-have-adhd/SKILL.md, strips YAML frontmatter, and stores the raw rule text in memory. Simultaneously, loadConfig() attempts to parse i-have-adhd.json for boolean flags including alwaysOn and hideStatus.

// extensions/i-have-adhd.ts (Lines 42-49, 61-78)
const rules = await loadRules(); // Strips frontmatter from SKILL.md
const config = await loadConfig(); // Parses i-have-adhd.json

CLI Flag and Slash Command Registration

The extension registers two primary user interaction surfaces:

  • --adhd Boolean flag: Registered via pi.registerFlag, this forces the mode enabled at process startup
  • /i-have-adhd slash command: Registered via pi.registerCommand, accepting on, off, or no arguments to toggle state at runtime
// extensions/i-have-adhd.ts (Lines 81-109)
pi.registerFlag("adhd", "boolean", "Enable ADHD-friendly mode");
pi.registerCommand("/i-have-adhd", (args) => {
  // Handles on/off/toggle logic
});

Session State Persistence

To maintain continuity across conversation sessions, the extension declares a STATE_ENTRY_TYPE constant and implements getSavedState(). This stores the enabled/disabled state in the session manager's custom entry storage, which is restored automatically during session_start or tree rebuild events.

The persistence mechanism ensures that users do not need to re-enable the mode manually when the context window refreshes or when resuming a previous session.

UI Status Indicator Setup

When active, the extension calls ctx.ui.setStatus to display a green "● ADHD ON" badge in the interface. The updateStatus() function respects the hideStatus configuration flag, allowing users to suppress the visual indicator while retaining the functional behavior.

Context Injection and Lifecycle Hooks

The core registration culminates in binding to three critical lifecycle events:

  1. session_start: Restores saved state and syncs context
  2. session_tree: Handles context tree rebuilds
  3. session_compact: Manages context compression events

The syncContext() function determines whether to inject rules using RULES_MESSAGE_TYPE or retract them using DISABLED_MESSAGE_TYPE. It leverages rulesAreInContext(), which internally calls latestMarkerIsActive() from extensions/context-compat.ts to check the current context state before modifying it.

// extensions/i-have-adhd.ts (Lines 34-59)
if (enabled && !rulesAreInContext(ctx)) {
  pi.sendMessage({ customType: RULES_MESSAGE_TYPE, content: rules });
} else if (!enabled && rulesAreInContext(ctx)) {
  pi.sendMessage({ customType: DISABLED_MESSAGE_TYPE, content: "ADHD MODE OFF" });
}

Runtime Behavior and Input Handling

Once registered, the extension monitors input events through a dedicated handler that processes:

  • Built-in skill aliases: Recognizes /skill:i-have-adhd commands
  • Stop phrases: Detects "stop adhd mode" or "normal mode" to automatically disable the feature
  • Confirmation messages: Optionally returns DISABLE_CONFIRMATION when turning off via voice command

The input handler (Lines 111-134 in extensions/i-have-adhd.ts) acts as a secondary filtering layer that interprets natural language disable requests without requiring explicit slash command syntax.

Code Examples

Enable ADHD mode at startup using the CLI flag:

pi --adhd

# or for OMP runtime

omp --adhd

Toggle mode dynamically within a session:

// Toggle via slash command
await pi.runCommand("/i-have-adhd on");

// Check if extension is active programmatically
if (ctx.sessionManager.hasCustomEntry("i-have-adhd-state")) {
  console.log("ADHD mode is currently enabled");
}

Disable via natural language input:

await pi.sendMessage({ text: "stop adhd mode" }); 
// Automatically triggers the disable handler and retracts rules

Summary

  • Registration entry point: extensions/i-have-adhd.ts implements the ExtensionAPI contract for both Pi and OMP runtimes
  • Configuration loading: Reads i-have-adhd.json for alwaysOn and hideStatus flags while loading rules from skills/i-have-adhd/SKILL.md
  • User interfaces: Exposes --adhd CLI flag and /i-have-adhd slash command for mode control
  • State management: Persists enabled/disabled state using STATE_ENTRY_TYPE and restores via getSavedState() on session events
  • Context manipulation: Injects RULES_MESSAGE_TYPE messages when enabled and DISABLED_MESSAGE_TYPE when disabled, checked via context-compat.ts utilities
  • Lifecycle integration: Hooks into session_start, session_tree, and session_compact events to maintain consistent context

Frequently Asked Questions

How does the i-have-adhd extension detect whether to inject rules into the context?

The extension uses the rulesAreInContext() helper function, which calls latestMarkerIsActive() from extensions/context-compat.ts. This utility checks whether the most recent custom message marker indicates an active rules injection, preventing duplicate insertions or premature retractions.

Can the i-have-adhd extension be enabled permanently without using the CLI flag?

Yes. Create an i-have-adhd.json file in your project root with {"alwaysOn": true}. The loadConfig() function reads this during registration and automatically enables the mode for all sessions regardless of CLI arguments.

What happens to the ADHD rules when the context window is compressed?

The extension listens to session_compact events and re-injects the rules if the mode remains enabled. Because state persists via STATE_ENTRY_TYPE, the syncContext() function ensures ADHD guidance remains present even after context tree optimization occurs.

Is the registration process identical between Pi and OMP runtimes?

Yes. Both runtimes use the same ExtensionAPI contract, so extensions/i-have-adhd.ts registers identically for Pi and OMP. The .opencode/plugins/i-have-adhd.mjs entry point adapts the same TypeScript implementation for the OpenCode runtime with no logic changes.

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 →