How to Integrate i-have-adhd with a Custom Agent Harness: Best Practices for 2024

The best way to integrate i-have-adhd with a custom agent harness is to load the TypeScript extension (for Pi/OMP harnesses) or the OpenCode plugin, register the adhd flag and /i-have-adhd command, and hook into session lifecycle events to synchronize the ruleset context.

Integrating i-have-adhd with a custom agent harness allows you to add an ADHD-friendly response layer to any OpenAI-style agent that follows the extension contract used by Pi, OMP, OpenCode, Claude Code, and Codex. The repository provides a clean, reusable architecture that separates the ruleset from the runtime logic, making integration straightforward across different harness types.

Core Integration Components

The i-have-adhd integration consists of three primary parts that work together to inject ADHD-friendly formatting rules into your agent's system prompt.

1. SKILL.md: The Ruleset Source of Truth

All behavioral rules live in a single human-readable file: skills/i-have-adhd/SKILL.md. This markdown file contains the complete instruction set that the model must follow when ADHD mode is active.

Both the TypeScript extension and the OpenCode plugin read from this file. Keeping rules in one location ensures consistency across all harness integrations.

2. TypeScript Extension for Pi/OMP Harnesses

The extensions/i-have-adhd.ts module provides full runtime control for Pi-compatible harnesses. It manages the enabled state, injects rules as system messages, and exposes user-facing controls.

Key functions in extensions/i-have-adhd.ts:

  • loadRules() (lines 46-64): Reads SKILL.md and strips YAML front-matter to extract the pure ruleset.
  • syncContext() (lines 18-33): Ensures rules appear in the active context only when enabled is true.
  • setEnabled() (lines 55-61): Toggles the mode, persists state to the session manager, updates UI status, and notifies the user.
  • pi.registerCommand("i-have-adhd", …) (lines 69-91): Exposes the /i-have-adhd slash command with subcommands (on, off, status check).

The extension stores state using a custom session entry keyed as i-have-adhd-state, ensuring the mode survives session reloads.

3. OpenCode Plugin for Minimal Integration

For OpenCode-based harnesses, .opencode/plugins/i-have-adhd.mjs provides a lighter alternative with always-on support.

Key features:

  • rulesetBody() (lines 38-43): Mirrors loadRules() — reads SKILL.md and removes YAML front-matter.
  • experimental.chat.system.transform (lines 59-78): Appends the ruleset to every system prompt when the flag file exists (~/.config/opencode/.i-have-adhd-always).

This plugin requires no interactive commands — the mode activates automatically based on filesystem state.

Integration Steps for Custom Harnesses

Follow this sequence when adding i-have-adhd support to your own agent harness.

Step 1: Load the Extension or Plugin

For Pi-based harnesses:

import { createPiAgent } from '@earendil-works/pi-coding-agent';
import iHaveAdhdExtension from './extensions/i-have-adhd';

async function main() {
  const pi = await createPiAgent({ /* your Pi config */ });
  
  // Install the i-have-adhd extension
  iHaveAdhdExtension(pi);
  
  await pi.start();
}
main();

For OpenCode harnesses:

import { OpenCode } from '@opencode-ai/sdk';
import iHaveAdhdPlugin from './.opencode/plugins/i-have-adhd.mjs';

async function run() {
  const oc = new OpenCode({
    plugins: [iHaveAdhdPlugin],
  });
  await oc.chat({ /* your chat config */ });
}
run();

Step 2: Register the Flag and Command

The extension automatically registers:

  • The adhd boolean flag for CLI opt-in (--adhd)
  • The /i-have-adhd slash command for runtime toggling

Custom harnesses must ensure their command parser and flag system expose these to users.

Step 3: Hook Session Lifecycle Events

For state persistence, your harness should invoke the extension's helpers at these session events:

Event Extension Helper Purpose
session_start restoreState() Read persisted i-have-adhd-state entry
session_tree syncContext() Inject or remove rules based on current state
session_compact syncContext() Maintain ruleset position after context compaction

The TypeScript extension subscribes to these events automatically when initialized with iHaveAdhdExtension(pi).

Step 4: Implement Always-On Mode (Optional)

For harnesses preferring automatic activation without user commands:


# Create the flag file in your harness's config directory

touch ~/.config/your-harness/.i-have-adhd-always

When this file exists, the OpenCode plugin's experimental.chat.system.transform hook prepends the ADHD ruleset to every system prompt. Reference hooks/always-on.mjs for Claude Code's implementation of the same pattern.

Programmatic Control for Testing

Automated tests can manipulate the integration directly:

// Toggle mode by writing to session state
pi.appendEntry('i-have-adhd-state', { enabled: true });

// Manually inject ruleset (bypasses normal flow)
pi.sendMessage(
  { customType: 'i-have-adhd-rules', content: '...' },
  { triggerTurn: false }
);

This approach matches how setEnabled() persists state internally (lines 55-61 in extensions/i-have-adhd.ts).

File Reference Map

File Purpose Integration Role
skills/i-have-adhd/SKILL.md Markdown ruleset Source of truth; loaded by all integrations
extensions/i-have-adhd.ts TypeScript extension Full-featured integration for Pi/OMP
.opencode/plugins/i-have-adhd.mjs OpenCode plugin Lightweight always-on support
hooks/always-on.mjs Claude Code script Reference implementation for custom hooks
tests/test_always_on_hooks.py Test suite Validates behavior across runtimes

Harness Compatibility Matrix

Harness Type Recommended Integration Entry Point
Pi/OMP TypeScript extension extensions/i-have-adhd.ts
OpenCode JavaScript plugin .opencode/plugins/i-have-adhd.mjs
Claude Code always-on hook hooks/always-on.mjs
Custom OpenAI-style Adapt plugin pattern Copy .opencode/plugins/i-have-adhd.mjs structure

Summary

  • Single source of truth: All rules live in skills/i-have-adhd/SKILL.md — never duplicate them in your harness.
  • Two integration paths: Use the TypeScript extension for interactive control (Pi/OMP) or the OpenCode plugin for always-on simplicity.
  • State persistence: The i-have-adhd-state session entry and flag file mechanisms ensure mode survival across sessions.
  • Command + flag surface: Expose /i-have-adhd for users and --adhd for CLI scripts to match upstream conventions.
  • Hook lifecycle events: restoreState() and syncContext() keep context synchronized automatically.

Frequently Asked Questions

How do I enable i-have-adhd permanently without typing commands?

Create an always-on flag file in your harness's configuration directory. For OpenCode, this is ~/.config/opencode/.i-have-adhd-always. The plugin's experimental.chat.system.transform hook detects this file and prepends the ADHD ruleset to every system prompt automatically.

Can I use i-have-adhd with a custom harness that isn't Pi or OpenCode?

Yes. The OpenCode plugin pattern in .opencode/plugins/i-have-adhd.mjs provides a minimal, portable reference. Copy its structure: read SKILL.md via rulesetBody(), strip the YAML front-matter, and inject the result into your system prompt using your harness's equivalent transform hook.

What happens if the SKILL.md file changes during a running session?

The extension reads SKILL.md fresh on each syncContext() call via loadRules() (lines 46-64). Ruleset updates take effect on the next context synchronization, typically at the start of a new user turn or session event.

How does state persist across session restarts?

The TypeScript extension writes to a custom session entry i-have-adhd-state using pi.appendEntry(). When the harness restarts, restoreState() reads this entry and reconstructs the previous enabled state before the first user interaction.

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 →