How to Restate State Across Turns for ADHD-Friendly Responses with i-have-adhd
The i-have-adhd extension persists ADHD mode across conversation turns by storing an enabled flag in custom session entries (i-have-adhd-state), then automatically restoring this state during session_start and session_tree events.
The ayghri/i-have-adhd repository provides a Pi-coding-agent extension that maintains ADHD-friendly formatting across multi-turn conversations. By implementing a robust state-restoration pattern, the extension ensures users enable ADHD mode once and retain consistent formatting throughout their session without manual reactivation.
The Persistence Architecture
Custom Session Entries as Persistent Storage
The extension leverages the Pi-coding-agent's session manager to store state across turns. When a user toggles ADHD mode, the setEnabled function in extensions/i-have-adhd.ts writes a custom entry of type i-have-adhd-state containing the boolean flag to the session branch. This entry survives session boundaries because the underlying session manager commits these entries to the session tree, making them available when the conversation resumes.
Automatic Restoration via Event Hooks
The extension registers listeners for session_start, session_tree, and session_compact events (lines 97-104 in extensions/i-have-adhd.ts). When these events fire—indicating a new turn or reload of a saved session—the extension calls restoreState to read the last saved entry and re-apply the correct UI status and ruleset. This hook-based approach ensures state restatement happens automatically without user intervention.
Core Implementation Mechanics
Loading Saved State with Fallbacks
In extensions/i-have-adhd.ts, the getSavedState function (lines 62-74) iterates over the session branch to locate the most recent i-have-adhd-state entry. If no entry exists, restoreState (lines 50-55) implements a fallback hierarchy: it checks the plugin flag (/i-have-adhd) or detects the presence of an .i-have-adhd-always file in the workspace root. This ensures sensible defaults when no explicit session history exists.
Synchronizing Context and UI
After resolving the flag value, the extension calls updateStatus (lines 7-17) to refresh the UI badge (ADHD ON) and syncContext (lines 23-36) to inject the ruleset. The syncContext function ensures the ADHD ruleset is injected only once per enabled session, preventing duplicate banners during multiple requests within the same turn. This deduplication is critical for maintaining clean, readable output.
Persisting User Toggles
When users execute /i-have-adhd on, /skill:i-have-adhd, or stop phrases, the setEnabled function (lines 59-65) updates the boolean flag and immediately persists it via pi.appendEntry("i-have-adhd-state", { enabled }). This guarantees that subsequent turns inherit the correct state, effectively restating the user's preference across the conversation boundary.
Practical Implementation Examples
The following examples demonstrate how the extension handles toggling and restoration:
// Toggling the mode from a chat turn
// User types: /i-have-adhd on
pi.registerCommand("i-have-adhd", {
description: "Toggle ADHD-friendly output for this session",
handler: async (args, ctx) => {
const arg = args.trim().toLowerCase();
if (arg === "on") setEnabled(true, ctx); // Saves a custom entry
else if (arg === "off") setEnabled(false, ctx);
else setEnabled(!enabled, ctx); // Toggle when no arg
},
});
// Restoring the flag when a new turn begins
pi.on("session_start", async (_ev, ctx) => restoreState(ctx));
pi.on("session_tree", async (_ev, ctx) => restoreState(ctx));
// Internal implementation of state persistence
function setEnabled(nextEnabled: boolean, ctx: ExtensionContext) {
enabled = nextEnabled;
// Persist the choice across turns
pi.appendEntry("i-have-adhd-state", { enabled });
// Update UI badge and inject/remove ruleset
updateStatus(ctx);
syncContext(ctx);
}
Summary
- The extension stores ADHD mode state in custom session entries (
i-have-adhd-state) that persist across turns via the Pi-coding-agent's session tree. - State restoration occurs automatically via
session_startandsession_treeevent listeners that invokerestoreState. - Fallback mechanisms include plugin flags and the
.i-have-adhd-alwaysfile for default behavior when no session history exists. - The
syncContextfunction prevents duplicate ruleset injection by tracking initialization state and ensuring single injection per session. - Users toggle mode via commands like
/i-have-adhd onwhich trigger immediate persistence throughsetEnabled.
Frequently Asked Questions
How does the extension remember ADHD mode between chat turns?
The extension writes a custom session entry (i-have-adhd-state) containing the enabled boolean every time the user toggles the mode. When a new turn begins, the restoreState function reads this entry from the session branch and re-applies the previous configuration, ensuring continuity across the conversation.
What happens if no previous state exists in the session?
If getSavedState finds no custom entry in the session branch, the extension falls back to checking the /i-have-adhd plugin flag or detecting an .i-have-adhd-always file in the workspace root. This ensures that users with persistent preferences or workspace-specific settings still receive ADHD-friendly output by default.
How does the extension prevent duplicate ADHD banners from appearing?
The syncContext function (lines 23-36 in extensions/i-have-adhd.ts) tracks whether the ruleset has already been injected for the current session. It only appends the ADHD ruleset from skills/i-have-adhd/SKILL.md if the context has not yet been synchronized, avoiding redundant formatting during multiple rapid requests.
Can I enable ADHD mode permanently across all sessions?
Yes. Creating an .i-have-adhd-always file in your workspace root causes restoreState to default to enabled when no explicit session entry exists. Alternatively, setting the plugin flag at the agent level provides persistent configuration that applies to all conversations in that workspace.
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 →