How Session Event Hooks Activate the i-have-adhd Skill: Hook Matcher Logic Explained

The i-have-adhd extension uses three Pi-runtime hooks—session_start, session_tree, and session_compact—to determine skill activation by checking saved state, CLI flags, and configuration before injecting ADHD-specific rules into the conversation context.

The ayghri/i-have-adhd repository implements a sophisticated hook matcher system that monitors session lifecycle events to activate its accessibility features. This TypeScript extension determines precisely when to enable its ADHD-specific skill by evaluating configuration states and synchronizing rules across session boundaries.

The Three Session Hooks That Drive Activation

The core hook matcher logic resides in extensions/i-have-adhd.ts, where the extension registers three critical Pi-runtime hooks that intercept session events. Each hook triggers specific state management functions to determine whether the skill should activate, restore previous state, or synchronize existing rules.

session_start and session_tree Hooks

Both the session_start and session_tree hooks invoke the restoreState function (lines 161-171) to evaluate activation conditions. The session_start hook fires at the beginning of new sessions, while session_tree triggers when the session tree reconstructs after reloads (lines 136-174).

These hooks perform the initial activation check by calling restoreState(ctx), which determines whether to inject the ADHD ruleset based on user configuration and persisted state.

session_compact Hook

The session_compact hook triggers syncContext (lines 134-158) during session log compaction when old markers are removed (lines 136-180). Unlike the start hooks, this hook focuses on maintaining consistency rather than initial activation, ensuring the rule-injection state matches the current enabled flag throughout the conversation lifecycle.

restoreState: Determining the Enabled State

The restoreState function implements the primary activation logic that decides whether the skill should inject its ruleset into the current session. This function evaluates four conditional sources in hierarchical order:

  1. Previously saved state via getSavedState
  2. CLI flag via pi.getFlag("adhd")
  3. User configuration via config.alwaysOn
  4. Filesystem marker via existsSync(alwaysOnFlag) checking for .i-have-adhd-always
// Inside restoreState – decides whether the skill is enabled
const enabledByDefault =
  pi.getFlag("adhd") === true ||
  config.alwaysOn === true ||
  existsSync(alwaysOnFlag);
enabled = savedState ?? enabledByDefault;

After determining the enabled boolean, the function updates the UI status via updateStatus and synchronizes the conversation context through syncContext(ctx).

syncContext: Rule Injection and Synchronization

The syncContext function manages the actual injection and removal of ADHD guidelines from the conversation. Located at lines 134-158 in extensions/i-have-adhd.ts, this function uses rulesAreInContext (lines 105-111) to check whether the latest rules marker (RULES_MESSAGE_TYPE) remains active and hasn't been superseded by a disabled marker (DISABLED_MESSAGE_TYPE).

// Inside syncContext – injects or removes the rule set
if (enabled && !injected) {
  pi.sendMessage({ customType: RULES_MESSAGE_TYPE, content: rules }, { triggerTurn: false });
}
if (!enabled && injected) {
  pi.sendMessage({ customType: DISABLED_MESSAGE_TYPE, content: DISABLED_NOTICE }, { triggerTurn: false });
}

When enabled is true but rules are missing, the function injects the ruleset from skills/i-have-adhd/SKILL.md. If the mode is disabled but stale rules persist, it sends a DISABLED_MESSAGE_TYPE notice to remove them.

Source Code Architecture

The activation logic spans three key files that work together to implement the session event hook matcher:

  • extensions/i-have-adhd.ts: Contains the hook registrations, restoreState activation logic, and syncContext synchronization (lines 105-180).
  • skills/i-have-adhd/SKILL.md: Stores the actual ADHD-friendly ruleset injected when activation conditions are met.
  • extensions/context-compat.ts: Provides the latestMarkerIsActive utility that rulesAreInContext uses to validate rule presence in the conversation context.

Summary

  • Three hooks trigger activation: session_start and session_tree handle initial activation via restoreState, while session_compact maintains state via syncContext.
  • Hierarchical configuration: The skill activates based on saved state, CLI --adhd flags, alwaysOn config, or the presence of a .i-have-adhd-always file.
  • Rule synchronization: The syncContext function ensures conversation context matches the enabled state by injecting RULES_MESSAGE_TYPE or removing it with DISABLED_MESSAGE_TYPE.
  • Marker-based validation: The rulesAreInContext function checks active markers to prevent duplicate rule injection or orphaned rulesets.

Frequently Asked Questions

What session events trigger the i-have-adhd skill activation?

The skill responds to three session events: session_start (new sessions), session_tree (session reconstruction after reloads), and session_compact (log compaction). The first two trigger full state restoration, while the compaction event only synchronizes existing rules with the current enabled state.

How does the hook matcher determine if the skill should be enabled?

The matcher evaluates four sources in restoreState: previously saved state from getSavedState, the CLI flag pi.getFlag("adhd"), the configuration value config.alwaysOn, and the filesystem marker .i-have-adhd-always. If any indicate activation (with saved state taking precedence), the skill injects its ruleset.

What prevents duplicate rule injection during long conversations?

The syncContext function uses rulesAreInContext (lines 105-111) to check for existing RULES_MESSAGE_TYPE markers before injection. If rules are already present and active, the function skips sending new messages. During compaction, it validates whether existing rules match the current enabled state and corrects any discrepancies.

Where does the extension store the actual ADHD guidelines?

The ruleset content resides in skills/i-have-adhd/SKILL.md, while the activation logic lives in extensions/i-have-adhd.ts (lines 136-180). The extensions/context-compat.ts file provides the marker validation utilities that prevent state desynchronization during session events.

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 →