How the i-have-adhd Plugin Toggles ADHD-Friendly Mode Using the /i-have-adhd Command
The i-have-adhd plugin implements a lightweight state machine that toggles ADHD-friendly output by updating an internal enabled flag, persisting the choice in session storage, and synchronizing rule-set injection with the model's context when users invoke the /i-have-adhd command.
The ayghri/i-have-adhd repository provides a Pi runtime extension that transforms how language models interact with ADHD users. When you issue the /i-have-adhd command, the plugin executes a precise toggling workflow that manages state persistence, context injection, and user feedback. Understanding this mechanism reveals how lightweight state machines can create seamless accessibility features in conversational AI interfaces.
Command Registration and Argument Parsing
The extension registers the toggle command through the Pi runtime in extensions/i-have-adhd.ts. At lines 69-71, the code calls pi.registerCommand to bind the i-have-adhd command to a handler function that receives the raw argument string and normalizes it to lower-case.
Argument parsing follows strict semantics defined at lines 73-88:
- No argument – Flips the current boolean state via
setEnabled(!enabled, ctx) "on"– Forces the mode active regardless of current state"off"or"stop"– Forces the mode inactive- Any other input – Triggers a usage warning to the user
The extension also maintains backward compatibility through a legacy alias. Invoking /skill:i-have-adhd routes through the same handler, ensuring existing workflows remain functional.
State Mutation and Persistence
When the handler determines the target state, it delegates to the setEnabled function located at lines 55-61. This function performs four critical operations atomically:
- Updates the in-memory
enabledflag - Appends a custom session entry using
STATE_ENTRY_TYPEto persist the boolean across the conversation - Updates the UI status badge to display "ADHD ON" when active
- Invokes
syncContextto modify the model's context window
State restoration occurs through the restoreState function at lines 45-53. On session initialization or when the session tree rebuilds, the plugin queries stored entries via getSavedState looking for the i-have-adhd-state marker. If no persisted state exists, the system falls back to checking the adhd flag or detecting an "always-on" file in the hooks directory, ensuring users with persistent ADHD-friendly preferences maintain their settings across sessions.
Context Synchronization with the Model
The syncContext function manages the actual injection and withdrawal of the ADHD-friendly rule set. This function checks the current context using latestMarkerIsActive to determine whether RULES_MESSAGE_TYPE or DISABLED_MESSAGE_TYPE markers already exist in the conversation history.
When enabling the mode, if no active rule marker exists, the extension injects the content from skills/i-have-adhd/SKILL.md as a hidden custom message. When disabling the mode, if a rules marker is present, the system injects a DISABLED_MESSAGE_TYPE notice to explicitly withdraw the previous instructions. This marker-based approach prevents duplicate rule injections and ensures the model receives unambiguous signaling about which behavioral protocol to follow.
Stop Phrase Detection and UI Feedback
The plugin monitors user input continuously for specific stop phrases defined in the STOP_PHRASES set at lines 102-108. Utterances matching "stop adhd mode" or "normal mode" automatically trigger the disable flow, mimicking the /i-have-adhd off command without requiring the user to remember slash-command syntax.
Visual feedback occurs immediately upon state change. The extension renders a status badge displaying "ADHD ON" when the mode is active and shows transient notifications indicating "ADHD mode enabled" or "ADHD mode disabled" to confirm user actions.
Practical Code Examples
The following TypeScript examples demonstrate how to interact with the toggle system programmatically:
// Toggle without arguments – flips the current state
await pi.runCommand("i-have-adhd", "");
// Explicitly enable ADHD-friendly formatting
await pi.runCommand("i-have-adhd", "on");
// Explicitly disable the mode
await pi.runCommand("i-have-adhd", "off");
// Legacy alias support
await pi.runCommand("skill:i-have-adhd", "");
For automatic detection, simply typing the following in conversation triggers the disable flow:
// These phrases are handled by the input hook at lines 102-108
"stop adhd mode"
"normal mode"
Summary
- The state machine tracks mode status through a boolean
enabledflag that persists viaSTATE_ENTRY_TYPEentries in the session storage. - Argument parsing supports toggle, explicit on/off, and legacy alias commands through the handler registered at
extensions/i-have-adhd.tslines 69-88. - Context injection uses marker types (
RULES_MESSAGE_TYPEandDISABLED_MESSAGE_TYPE) to ensure the model receives the ADHD-friendly rules fromskills/i-have-adhd/SKILL.mdexactly once. - Stop phrases provide conversational exit ramps, allowing users to disable the mode by typing natural language rather than slash commands.
- Key files include
extensions/i-have-adhd.tsfor core logic,extensions/context-compat.tsfor context utilities, andhooks/always-on.*for persistent activation.
Frequently Asked Questions
How do I explicitly turn ADHD-friendly mode on or off instead of toggling?
Pass the string argument "on" or "off" to the command. According to the source code at lines 73-88 in extensions/i-have-adhd.ts, providing "on" forces the mode active while "off" or "stop" forces it inactive, bypassing the default toggle behavior that simply flips the current state.
Where does the plugin store my ADHD mode preference between messages?
The plugin persists the boolean state in the session's custom entries using the STATE_ENTRY_TYPE identifier. The restoreState function at lines 45-53 retrieves this via getSavedState, looking specifically for the i-have-adhd-state entry. If no entry exists, it checks for an "always-on" file or the adhd flag to determine the initial state.
Can I disable ADHD mode by typing in the conversation rather than using a command?
Yes. The extension monitors input for STOP_PHRASES defined at lines 102-108, which include the phrases "stop adhd mode" and "normal mode". When detected, the input hook automatically invokes the same disable logic as /i-have-adhd off, removing the rules from the model's context and updating the UI badge.
Which source files contain the core toggling logic for the /i-have-adhd command?
The primary implementation resides in extensions/i-have-adhd.ts, which contains the command registration, argument parsing, and setEnabled function. Context synchronization utilities live in extensions/context-compat.ts, while the actual ADHD-friendly rules injected into the model are stored in skills/i-have-adhd/SKILL.md. Optional always-on behavior is configured through files in the hooks/ directory.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →