How the Claude Code Always-On Mechanism Works in i-have-adhd
Claude Code's always-on mechanism automatically loads the ADHD-friendly skill at every session start by checking for a flag file and injecting rules from SKILL.md via a SessionStart hook.
The ayghri/i-have-adhd repository implements a persistent, opt-in system that makes ADHD-friendly response formatting available without manual activation. This article explains the complete technical flow, from hook registration to rule injection, based on the actual source code implementation.
How the SessionStart Hook Triggers the Mechanism
The always-on workflow begins with hooks/hooks.json, which declares a SessionStart hook that Claude executes at the beginning of every new session:
{
"hooks": {
"SessionStart": "node hooks/always-on.mjs"
}
}
When a Claude session initializes, this hook runs the Node module hooks/always-on.mjs. The mechanism is entirely automatic—no user interaction is required after the initial opt-in.
The Always-On Module Execution Flow
The file hooks/always-on.mjs performs a five-step validation and injection process:
1. Resolve the Configuration Directory
The module first determines where Claude stores its configuration:
const configDir = process.env.CLAUDE_CONFIG_DIR || path.join(os.homedir(), '.claude');
The CLAUDE_CONFIG_DIR environment variable takes precedence; otherwise, it defaults to ~/.claude.
2. Verify the Opt-In Flag
The script checks for the existence of .i-have-adhd-always in the config directory:
const flagPath = path.join(configDir, '.i-have-adhd-always');
if (!fs.existsSync(flagPath)) {
process.exit(0); // Silent exit—no modification to session
}
If the flag file is absent, the script exits immediately with status 0, ensuring the hook never blocks session startup for non-opted-in users.
3. Locate and Load the Skill Definition
With opt-in confirmed, the module resolves the skill path relative to its own location:
const scriptDir = path.dirname(fileURLToPath(import.meta.url));
const skillPath = path.resolve(scriptDir, '../skills/i-have-adhd/SKILL.md');
4. Process the Skill Content
The script reads SKILL.md, strips its YAML front-matter, and cleans trailing newlines:
const content = fs.readFileSync(skillPath, 'utf8');
const cleaned = content.replace(/^---[\s\S]*?---/, '').trim();
This extraction isolates the actual rule instructions from metadata headers.
5. Emit the Ruleset to stdout
Finally, the module outputs a prefixed message that Claude captures and injects:
console.log(`[Injecting i-have-adhd skill rules...]\n${cleaned}`);
Claude receives this stdout output and applies the ruleset to every subsequent response in the session.
Platform Fallback Implementations
The repository includes alternative implementations for environments where Node is unavailable.
POSIX Shell Fallback: hooks/always-on.sh
The bash script mirrors the Node logic using standard Unix utilities:
#!/bin/bash
set -e
# Determine config directory
CONFIG_DIR="${CLAUDE_CONFIG_DIR:-$HOME/.claude}"
FLAG_FILE="$CONFIG_DIR/.i-have-adhd-always"
# Check opt-in flag
[ -f "$FLAG_FILE" ] || exit 0
# Resolve skill path relative to script location
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
SKILL_FILE="$SCRIPT_DIR/../skills/i-have-adhd/SKILL.md"
# Strip front-matter with awk and output
awk '/^---$/{if(++c==2){p=1;next}}p' "$SKILL_FILE" | sed -e 's/^[[:space:]]*//; $a\' | xargs -0 printf '[Injecting i-have-adhd skill rules...]\n%s'
PowerShell Version
A PowerShell implementation (hooks/always-on.ps1) provides equivalent functionality for Windows environments without Node.js.
Managing the Always-On State
| Action | Command |
|---|---|
| Enable | touch ~/.claude/.i-have-adhd-always |
| Disable permanently | rm ~/.claude/.i-have-adhd-always |
| Disable for current session only | Send "stop adhd mode" to Claude |
The flag file is read on every SessionStart event, so changes take effect immediately across restarts without restarting Claude itself.
Error Handling and Safety Guarantees
The always-on mechanism is designed to never disrupt normal Claude operation:
- All failure paths exit with status 0, preventing session blocking
- Missing skill files result in silent no-op behavior
- The
catch(()=>{})pattern in debugging snippets suppresses error propagation - No network calls or external dependencies are required after installation
Summary
- The always-on mechanism is triggered by a
SessionStarthook declared inhooks/hooks.json. hooks/always-on.mjschecks for.i-have-adhd-alwaysflag file before injecting rules.- Rules are extracted from
../skills/i-have-adhd/SKILL.mdby stripping YAML front-matter. - Output to stdout with
[Injecting i-have-adhd skill rules...]prefix activates the behavior. - POSIX and PowerShell fallbacks ensure cross-platform compatibility without Node.js.
Frequently Asked Questions
How do I enable Claude Code always-on mode for the ADHD skill?
Create an empty file named .i-have-adhd-always in your Claude config directory (typically ~/.claude). The next Claude session will automatically activate the ADHD-friendly response style. No file content is required—the mere existence of the flag enables the mechanism.
Why does the always-on script exit silently instead of showing errors?
The design prioritizes non-blocking session startup. By exiting with status 0 on any failure—including missing flag files, permission issues, or missing skill definitions—the hook ensures Claude sessions initialize normally regardless of i-have-adhd configuration state.
Can I temporarily disable the always-on behavior without deleting the flag file?
Yes. Sending "stop adhd mode" to Claude disables rule injection for the remainder of that specific session. The flag file remains intact, so the skill will reactivate on the next session start. This provides granular control without permanent configuration changes.
What happens if the skill file is moved or corrupted?
The Node script in hooks/always-on.mjs would encounter a file read error and exit with status 0, identical to the no-flag behavior. The POSIX fallback uses set -e for early exit on failures. In both cases, Claude operates normally without the ADHD modifications—no error messages appear to the user.
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 →