# How to Restate State Across Turns for ADHD-Friendly Responses with i-have-adhd

> Learn how to restate state across turns for ADHD-friendly responses using the i-have-adhd extension. Discover how it maintains ADHD mode seamlessly through conversation turns.

- Repository: [Ayoub Ghriss/i-have-adhd](https://github.com/ayghri/i-have-adhd)
- Tags: how-to-guide
- Published: 2026-08-08

---

**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`](https://github.com/ayghri/i-have-adhd/blob/main/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`](https://github.com/ayghri/i-have-adhd/blob/main/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`](https://github.com/ayghri/i-have-adhd/blob/main/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:

```typescript
// 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
  },
});

```

```typescript
// 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));

```

```typescript
// 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_start` and `session_tree` event listeners that invoke `restoreState`.
- **Fallback mechanisms** include plugin flags and the `.i-have-adhd-always` file for default behavior when no session history exists.
- The `syncContext` function prevents duplicate ruleset injection by tracking initialization state and ensuring single injection per session.
- Users toggle mode via commands like `/i-have-adhd on` which trigger immediate persistence through `setEnabled`.

## 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`](https://github.com/ayghri/i-have-adhd/blob/main/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`](https://github.com/ayghri/i-have-adhd/blob/main/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.