How Claude Code Always-On Mode Works via hooks/always-on.mjs

Claude Code's always-on mode automatically injects ADHD-friendly response rules at the start of every session by executing hooks/always-on.mjs through a SessionStart hook that checks for a flag file and outputs sanitized rules from SKILL.md to stdout.

The ayghri/i-have-adhd repository provides a Claude Code plugin designed to support neurodivergent users through persistent behavioral modifications. The always-on mode ensures the complete ADHD rule set defined in the project’s SKILL.md automatically prepends every Claude response without requiring manual activation commands. This functionality is implemented primarily through the Node.js module hooks/always-on.mjs, which is triggered automatically via hook configuration when sessions start, resume, or refresh.

How the SessionStart Hook Triggers Always-On Mode

The always-on mode activates through a SessionStart hook defined in hooks/hooks.json. This hook matcher triggers on session state changes including startup, resume, clear, and compact events.

When a matching session event occurs, Claude Code executes the following command:

node -e "(async()=>{const root=process.env.CLAUDE_PLUGIN_ROOT||process.env.PLUGIN_ROOT;if(root)await import(require('node:url').pathToFileURL(require('node:path').join(root,'hooks','always-on.mjs')).href)})().catch(()=>{})"

This inline Node.js command resolves the plugin root directory from environment variables (CLAUDE_PLUGIN_ROOT or PLUGIN_ROOT), constructs a file URL path to hooks/always-on.mjs, and dynamically imports the module. The trailing .catch(()=>{}) ensures execution failures never block the session from starting.

Inside hooks/always-on.mjs: Step-by-Step Execution

The hooks/always-on.mjs script follows a strict six-step pipeline to safely load and inject the ADHD rule set.

Flag File Detection and Opt-In Check

The script first determines the configuration directory using the CLAUDE_CONFIG_DIR environment variable, defaulting to ~/.claude if unset (lines 16-18). It checks for the existence of a flag file at /.i-have-adhd-always within that directory.

If the flag file does not exist, the script exits silently with process.exit(0), allowing the session to proceed without modification (line 20).

Loading and Sanitizing SKILL.md

Upon confirming the opt-in flag, the script locates the master rule set by resolving SKILL.md relative to the script’s own directory using import.meta.dirname (lines 22-25). This approach avoids reliance on user-controlled environment variables for path resolution.

The script reads the file as UTF-8 and performs content sanitization (lines 27-34):

  • Strips YAML front-matter blocks (content between --- delimiters) using a regular expression
  • Removes trailing newlines to ensure clean output formatting

Rule Injection and Output

The cleaned ruleset is written to stdout prefixed with an activation notice indicating that ADHD MODE ACTIVE (always-on) is engaged (lines 36-40). Claude Code captures this standard output and prepends the content to every subsequent response for the session. The notice includes instructions for disabling the mode temporarily ("stop adhd mode") or permanently (deleting the flag file).

Safe Failure Handling

The implementation includes defensive error handling at multiple levels (lines 41-44). Any exception thrown during flag checking, file reading, or output operations is caught silently, and the process exits with code 0. This guarantees that a corrupted SKILL.md file or missing permissions never prevent Claude Code from starting.

Shell Fallback for Non-Node Environments

For environments where Node.js is unavailable, the repository provides hooks/always-on.sh, a POSIX shell script that mirrors the Node.js implementation exactly. This fallback ensures cross-platform reliability by duplicating the flag file check, YAML front-matter stripping logic, and safe exit behavior using standard shell utilities.

Enabling and Disabling Always-On Mode

To enable always-on mode permanently, create the flag file in your Claude configuration directory:

mkdir -p "$HOME/.claude"
touch "$HOME/.claude/.i-have-adhd-always"

To disable always-on mode for the current session only, type the following in Claude:


stop adhd mode

To permanently disable always-on mode, remove the flag file:

rm "$HOME/.claude/.i-have-adhd-always"

Summary

  • SessionStart hook: Located in hooks/hooks.json, triggers on startup|resume|clear|compact events to launch hooks/always-on.mjs via a dynamic Node.js import command.
  • Opt-in mechanism: Checks for ~/.claude/.i-have-adhd-always (or $CLAUDE_CONFIG_DIR/.i-have-adhd-always) and exits silently if absent.
  • Content processing: Reads SKILL.md, strips YAML front-matter with regex, removes trailing newlines, and prepends an activation header.
  • Safety guarantees: All failures exit with code 0, ensuring session startup never blocks; a POSIX shell fallback (hooks/always-on.sh) provides Node-independent support.
  • Rule injection: Cleaned rules output to stdout are automatically prepended to every Claude response for the duration of the session.

Frequently Asked Questions

What happens if the flag file is missing?

If ~/.claude/.i-have-adhd-always does not exist when hooks/always-on.mjs runs, the script calls process.exit(0) immediately and the session proceeds normally without loading ADHD mode rules. This design ensures the plugin is strictly opt-in and never interferes with standard Claude Code usage.

Can I use always-on mode without Node.js installed?

Yes. The repository includes hooks/always-on.sh, a POSIX-compliant shell script that implements identical logic for flag checking, YAML front-matter removal, and rule output. This fallback ensures the always-on mode functions in containerized or minimal environments where Node.js may not be available.

How do I temporarily disable always-on for just one session?

Type stop adhd mode in the Claude Code chat interface. This command disables the ADHD rule injection for the current session only without deleting the flag file, allowing you to resume always-on mode automatically the next time you start a session.

Where does the plugin store the configuration flag?

The script checks the CLAUDE_CONFIG_DIR environment variable first, defaulting to the ~/.claude directory if unset. The specific file path is .i-have-adhd-always within that directory. This location is consistent across both the Node.js and shell implementations.

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 →