How Platform Adapters Load the i-have-adhd Ruleset: Complete Technical Guide

Platform adapters load the i-have-adhd ruleset by reading SKILL.md from the skills directory, determining the initial enabled state from configuration flags and session storage, then synchronizing the rules with the conversation context through message injection.

The i-have-adhd repository implements a platform adapter pattern that injects a static ADHD-friendly response ruleset into AI model contexts. This guide examines the complete loading pipeline as implemented in extensions/i-have-adhd.ts, from file system access to runtime synchronization.

Phase 1: Reading the Rules File

The adapter begins by loading the canonical ruleset from persistent storage.

Locating and Parsing SKILL.md

In extensions/i-have-adhd.ts (lines 14-21), the adapter resolves the path to skills/i-have-adhd/SKILL.md and reads its contents:

// From extensions/i-have-adhd.ts
const skillPath = path.join(ctx.extensionPath, 'skills', 'i-have-adhd', 'SKILL.md');
const rawContent = fs.readFileSync(skillPath, 'utf-8');

The stripFrontmatter helper (lines 52-59) removes any YAML metadata, leaving only the ten plain-text rules:

// From extensions/i-have-adhd.ts
function stripFrontmatter(content: string): string {
  // Removes --- delimited YAML blocks from the start of the file
  return content.replace(/^---\n[\s\S]*?\n---\n?/, '').trim();
}

If the file is missing or empty, the adapter throws a descriptive error (lines 65-76), halting initialization rather than proceeding with partial state.

Phase 2: Determining the Initial Enabled State

The adapter evaluates multiple configuration sources to decide whether to activate the ruleset at session start.

The restoreState Function

The restoreState function (lines 61-69) checks four sources in priority order:

  1. Previous session entry – Looks for STATE_ENTRY_TYPE in saved session data
  2. Pi runtime flag – Checks pi.getFlag("adhd") for explicit command-line or environment configuration
  3. alwaysOn configuration – Reads i-have-adhd.json via loadConfig for persistent preferences
  4. Sentinel file – Detects .i-have-adhd-always in the workspace root

The resulting boolean is stored in the module-level enabled variable, which persists across the session lifetime.

Hook Registration

The adapter registers for three lifecycle hooks in hooks/hooks.json:

{
  "hooks": ["session_start", "session_tree", "session_compact"]
}

Each hook triggers syncContext to ensure the ruleset state remains consistent as the conversation evolves.

Phase 3: Synchronizing Rules with Conversation Context

The syncContext function (lines 34-59) implements the core injection and removal logic.

Rule Injection

When enabled is true and no active rules marker exists, the adapter sends:

// From extensions/i-have-adhd.ts, lines 38-45
pi.sendMessage({
  type: RULES_MESSAGE_TYPE,
  content: RULES_HEADER + '\n\n' + strippedRules
});

The RULES_HEADER constant identifies this message as carrying the ADHD ruleset, while strippedRules contains the ten parsed guidelines from SKILL.md.

Rule Removal

When enabled transitions to false, the adapter sends a disable marker:

// From extensions/i-have-adhd.ts
pi.sendMessage({
  type: DISABLED_MESSAGE_TYPE,
  content: DISABLED_NOTICE
});

Marker Validation

The helper latestMarkerIsActive from context-compat.ts (referenced at lines 5-11) inspects session marker history to confirm whether rules are currently visible to the model. This prevents redundant injections and ensures only the newest state marker counts.

User Interaction Mechanisms

Command Registration

The adapter exposes the /i-have-adhd command through pi.registerCommand, with /skill:i-have-adhd as an alias. The command accepts:

  • No arguments – Toggles the current state
  • on – Forces rules injection
  • off – Forces rules removal

Stop Phrases

Input matching STOP_PHRASES ("stop adhd mode", "normal mode") automatically triggers disable:

// Conceptual usage
User: "Please use normal mode"
→ Adapter detects match → Calls setEnabled(false) → Returns DISABLE_CONFIRMATION

Status UI

When active and hideStatus is not configured, the adapter displays a status badge:

ctx.ui.setStatus('● ADHD ON');

Configuration Examples

Runtime Toggle


# Enable for current session

> /i-have-adhd on

Persistent Activation

Create i-have-adhd.json in the agent root:

{
  "alwaysOn": true,
  "hideStatus": false
}

Or use the sentinel file approach:

touch .i-have-adhd-always

Summary

  • File loading: extensions/i-have-adhd.ts reads skills/i-have-adhd/SKILL.md and strips YAML frontmatter via stripFrontmatter
  • State initialization: restoreState evaluates session history, runtime flags, JSON config, and sentinel files to set the enabled boolean
  • Context synchronization: syncContext injects rules via RULES_MESSAGE_TYPE or removes them via DISABLED_MESSAGE_TYPE, validated by latestMarkerIsActive from context-compat.ts
  • User control: Commands, stop phrases, and configuration files provide multiple interfaces for managing the ruleset lifecycle

Frequently Asked Questions

What file contains the actual ADHD response rules?

The rules live in skills/i-have-adhd/SKILL.md as plain Markdown. The adapter loads this file once per session, removes any YAML frontmatter, and injects the content into model context when enabled.

How does the adapter know whether to enable the rules at startup?

It calls restoreState, which checks four sources in order: previous session state, the adhd runtime flag, the alwaysOn config value, and the presence of .i-have-adhd-always. The first positive match determines initial state.

Can users disable the rules without using a command?

Yes. Saying "stop adhd mode" or "normal mode" triggers automatic detection via STOP_PHRASES matching. The adapter then disables the mode and may return the fixed confirmation string DISABLE_CONFIRMATION.

Where is the marker validation logic implemented?

The latestMarkerIsActive helper resides in extensions/context-compat.ts. It inspects session marker history to determine whether the most recent state change is still active in the model's context view.

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 →