How State Is Restored When a Session Starts or Resumes in the Pi Extension

The Pi extension restores ADHD mode by reading persisted session entries, checking CLI flags or marker files for default-on behavior, and re-injecting the ruleset into the model context whenever a session_start or session_tree event fires.

The ayghri/i-have-adhd repository provides a Pi extension that maintains ADHD-friendly formatting across conversation sessions. When a session begins or a saved conversation tree reloads, the extension must reconstruct the active state to ensure consistent behavior. This restoration process balances user preferences, default configuration, and the current model context.

The State Restoration Pipeline

The restoration logic is orchestrated in extensions/i-have-adhd.ts through a four-step pipeline that combines persistence lookup with configuration fallbacks.

Step 1: Retrieving Saved State from the Session Tree

The getSavedState function searches the session history for previous ADHD mode configurations. It traverses the conversation tree via ctx.sessionManager.getBranch(), filtering for entries of type i-have-adhd-state and returning the most recent enabled value.

This check occurs at lines 66-80 in extensions/i-have-adhd.ts. If the user previously toggled the mode during the conversation, that persisted value takes precedence over all other settings.

Step 2: Evaluating Default-On Conditions

When no saved state exists, restoreState (lines 145-150) determines whether ADHD mode should activate by default. The logic checks two sources:

  • CLI Flag: pi.getFlag("adhd") detects if the user launched Pi with the --adhd flag
  • Marker File: The existence of a .i-have-adhd-always file in the working directory signals "always-on" behavior

The final enabled status is computed as enabled = savedState ?? enabledByDefault, ensuring explicit user choices override default settings.

Step 3: Synchronizing the UI and Model Context

Once the enabled status is determined, the extension updates the interface and model context through two coordinated operations:

UI Update: The updateStatus(ctx) function (lines 101-108) sets the status bar indicator to "ADHD ON" when enabled, or clears it when disabled.

Context Injection: The syncContext(ctx) function (lines 118-143) manages the actual ruleset present in the model's context. It injects the ADHD rules from skills/i-have-adhd/SKILL.md when enabling the mode, or inserts a "disabled" notice when turning it off. To prevent duplication, it uses latestMarkerIsActive from extensions/context-compat.ts (lines 41-60) to detect whether the ruleset marker is already present in the current context.

Event Hooks That Trigger Restoration

Restoration occurs automatically through two distinct lifecycle hooks registered at lines 219-220 of extensions/i-have-adhd.ts:

  • session_start: Fires when a brand-new conversation session initializes
  • session_tree: Fires when an existing session tree is restored from disk, such as after resuming a paused session or syncing across devices

Both events invoke restoreState, ensuring the ADHD mode is consistently re-hydrated regardless of whether the user starts fresh or resumes previous work.

Practical Implementation Examples

The following patterns demonstrate how the restoration logic behaves in different scenarios:

// Launch Pi with ADHD mode enabled via CLI flag
// The restoreState function detects pi.getFlag("adhd") === true
pi.run({ flags: { adhd: true } });
// Result: enabled set to true, UI updated, rules injected into context
// Create an always-on marker file
// This bypasses the need for CLI flags in future sessions
await fs.writeFile('.i-have-adhd-always', '');
// Subsequent sessions will default to enabled unless explicitly toggled off
// Manual toggle during a session (persists across restarts)
await pi.sendCommand("/i-have-adhd on");
// Extension appends {type: 'i-have-adhd-state', enabled: true} to session tree
// On next session_tree event, getSavedState() reads this entry automatically
// Checking context synchronization
// Uses latestMarkerIsActive from extensions/context-compat.ts
if (!latestMarkerIsActive(ctx.messages, 'adhd-rules')) {
  await syncContext(ctx); // Injects rules only if missing
}

Summary

  • Persistence First: The extension checks i-have-adhd-state entries in the session tree before applying defaults, preserving explicit user toggles across restarts.
  • Default-On Logic: ADHD mode activates automatically via the --adhd CLI flag or the presence of a .i-have-adhd-always marker file when no saved state exists.
  • Dual Event Hooks: Both session_start and session_tree events trigger restoreState, ensuring consistent behavior for new and resumed sessions.
  • Context Deduplication: The latestMarkerIsActive utility prevents duplicate rule injection by scanning existing context messages before adding the ADHD ruleset.

Frequently Asked Questions

What happens if no previous state is saved and no default-on flags are set?

If getSavedState returns undefined and neither the --adhd flag nor the .i-have-adhd-always file exists, restoreState sets enabled to false. The UI clears any status indicators and syncContext ensures no ADHD rules are present in the model context, effectively running Pi in standard mode.

How does the extension prevent duplicate rule injection when restoring state?

The syncContext function calls latestMarkerIsActive from extensions/context-compat.ts to scan the current context messages for an existing ADHD ruleset marker. If the marker is found, the function skips injection; if missing, it injects the rules. This check runs every time state is restored, preventing accumulation of duplicate instructions in long-running or frequently resumed sessions.

What is the difference between the session_start and session_tree events?

The session_start event fires exclusively when initializing a completely new conversation session with no prior history. The session_tree event fires when Pi loads or reloads an existing conversation tree from storage, which occurs when resuming a paused session, restoring from backup, or syncing across devices. The extension listens to both events at lines 219-220 of extensions/i-have-adhd.ts to ensure ADHD state is restored in every possible entry scenario.

Can I force ADHD mode on for all sessions without manually enabling it each time?

Yes. Create an empty file named .i-have-adhd-always in your working directory. The restoreState function checks for this file at lines 145-150, and if present, sets enabledByDefault to true. Alternatively, configure your Pi launcher to always include flags: { adhd: true }, which achieves the same result without creating marker files.

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 →