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-adhdto 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, andinputmanage state across the full session lifecycle - Persistence guarantee:
session_startandsession_treeensure mode survives restores and rebuilds - Compaction safety:
session_compactre‑injects rules after context summarization - Interactive control:
inputhandles real‑time command and phrase detection - System‑level override: Global
SessionStartcommand enables always‑on mode via.i-have-adhd-alwaysflag file - Implementation files: All hooks defined in
extensions/i-have-adhd.tswith global command inhooks/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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →