i‑Have‑ADHD Extension Hooks: session_start, session_tree, and Full Lifecycle Registration

The i‑have‑adhd extension registers four Pi‑coding‑agent hooks: session_start, session_tree, session_compact, and input, plus a global SessionStart command for always‑on mode.

The i‑have‑adhd extension for Pi‑coding‑agent manages ADHD‑friendly response rules across conversation lifecycles by hooking into key session events. Understanding which hooks this extension registers helps developers debug state synchronization issues, extend the plugin, or build similar extensions that persist user preferences across session restores and compactions.

session_start Hook: Restoring State on Session Creation

The session_start hook fires at the beginning of any new session or when a session is restored from storage. In extensions/i-have-adhd.ts lines 193‑194, the extension restores the saved ADHD‑mode state—or falls back to the default/always‑on flag—and immediately updates the UI status bar.

This hook ensures users don't lose their preferred mode between conversations. The implementation checks persistent storage for a previous toggle state, then calls the internal updateStatus() method to reflect the current mode in the interface.

Code location: extensions/i-have-adhd.ts:193‑194

session_tree Hook: Handling Tree Rebuilds

The session_tree hook triggers whenever the session tree is rebuilt, which occurs after resume operations or when the context is cleared. Lines 199‑200 of extensions/i-have-adhd.ts execute identical restoration logic to session_start.

Tree rebuilds can orphan extension state because the entire conversation structure is reconstructed from serialized data. By re‑registering this hook separately from session_start, the extension handles edge cases where a session persists but its tree representation changes mid‑conversation.

Code location: extensions/i-have-adhd.ts:199‑200

session_compact Hook: Re‑injecting Rules After Summarization

The session_compact hook responds to session compaction events where older messages are summarized to conserve context window space. Lines 207‑208 of extensions/i-have-adhd.ts re‑inject the ADHD rules if the mode remains enabled.

This is critical because compaction drops custom metadata markers that the extension uses to track whether rules are active. Without this hook, users would silently lose ADHD‑friendly formatting after their conversation grows long enough to trigger automatic summarization.

Code location: extensions/i-have-adhd.ts:207‑208

input Hook: Command Detection and Mode Toggling

The input hook runs on every user message and serves two purposes in lines 193‑221:

  • Legacy command detection: Recognizes /skill:i-have-adhd to enable the mode
  • Stop phrase handling: Detects "stop adhd mode" or "normal mode" to disable it, optionally returning a confirmation response

Unlike the other hooks that manage state persistence, input provides the interactive control surface. The hook parses message content before it reaches the main agent loop, allowing immediate mode switches without polluting the conversational context with command syntax.

Code location: extensions/i-have-adhd.ts:193‑221

Global SessionStart Command: Always‑On Mode

Beyond the extension's own hooks, the repository declares a global SessionStart command in hooks/hooks.json lines 4‑13. This command executes a Node script that imports hooks/always-on.mjs when the environment variable CLAUDE_PLUGIN_ROOT or PLUGIN_ROOT points to the plugin directory.

The script checks for the hidden flag file .i-have-adhd-always. If present, it triggers the extension to start with ADHD‑mode enabled regardless of previous session state. This provides system‑level configuration for users who always want ADHD‑friendly responses.

Code location: hooks/hooks.json:4‑13

Hook Execution Order and Interaction

The hooks execute in predictable sequences depending on user actions:

Scenario Hooks Fired Result
New conversation SessionStart (global) → session_start Always‑on check, then state restoration
Restore from storage session_start Previous mode restored
Tree rebuild after clear session_tree Mode re‑applied to fresh tree
Long conversation compaction session_compact Rules re‑injected after summarization
User types toggle command input Immediate mode change

Working with the Hook System Programmatically

Enable ADHD mode from another plugin using the ExtensionAPI:

// Assuming `pi` is the ExtensionAPI instance
pi.sendMessage({
  customType: "i-have-adhd-enabled",
  content: "ADHD mode activated",
  display: false,
});

Manually emit a session‑start hook for testing:

await pi.emit("session_start", {});

Check whether rules are currently active in context:

import { contextMessages, latestMarkerIsActive } from "./context-compat";

const haveRules = latestMarkerIsActive(
  contextMessages(ctx.sessionManager),
  "i-have-adhd-rules",
  "i-have-adhd-disabled"
);

Toggle via built‑in command:

// In chat
/i-have-adhd on   // enable
/i-have-adhd off  // disable

Key Source Files

File Purpose
extensions/i-have-adhd.ts Core extension; registers session_start, session_tree, session_compact, input
hooks/hooks.json Global SessionStart command declaration
hooks/always-on.mjs Flag‑file check implementation
extensions/context-compat.ts Helper utilities: contextMessages, latestMarkerIsActive
skills/i-have-adhd/SKILL.md Actual ADHD‑friendly rule definitions

Summary

  • Four lifecycle hooks: session_start, session_tree, session_compact, and input manage state across the full session lifecycle
  • Persistence guarantee: session_start and session_tree ensure mode survives restores and rebuilds
  • Compaction safety: session_compact re‑injects rules after context summarization
  • Interactive control: input handles real‑time command and phrase detection
  • System‑level override: Global SessionStart command enables always‑on mode via .i-have-adhd-always flag file
  • Implementation files: All hooks defined in extensions/i-have-adhd.ts with global command in hooks/hooks.json

Frequently Asked Questions

What is the difference between session_start and SessionStart hooks?

session_start (lowercase) is the extension‑internal hook registered in extensions/i-have-adhd.ts that restores saved state. SessionStart (capitalized) is the global framework command declared in hooks/hooks.json that runs external scripts before any extension loads. The global command checks for always‑on mode; the internal hook handles per‑session state restoration.

Why does the extension need both session_start and session_tree?

session_start fires on session creation or restore, while session_tree fires when the conversation tree is rebuilt without creating a new session. Tree rebuilds occur after context clears or certain resume operations that preserve session metadata but reconstruct the message structure. Separate hooks ensure state synchronization in both cases.

How does session_compact prevent rule loss?

Session compaction summarizes older messages to save context window space, which strips custom metadata markers the extension uses to track active rules. The session_compact hook detects this operation and re‑injects the ADHD rule set from skills/i-have-adhd/SKILL.md if the mode remains enabled, ensuring continuous formatting without user intervention.

Can I trigger these hooks manually for testing?

Yes. Use await pi.emit("session_start", {}) or similar with the ExtensionAPI instance. The input hook accepts raw message objects, and session_compact can be simulated by calling the compaction API directly. However, SessionStart (global) requires actual framework initialization and cannot be triggered from within an active session.

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 →