How the SessionStart Hook Works in Claude Code Plugins

The SessionStart hook in Claude Code plugins automatically executes custom scripts whenever a new chat session begins, allowing developers to inject system messages or preload configuration without user intervention.

The SessionStart hook is a declarative mechanism that enables Claude Code plugins to run initialization code at the start of every chat session. In the ayghri/i-have-adhd open-source repository, this hook powers an "always-on" mode that automatically applies ADHD-friendly guidelines to every conversation. Understanding this implementation provides a complete reference for building plugins that require persistent session initialization.

How the SessionStart Hook Is Declared

Claude Code plugins register session-level automation through a hooks.json manifest file. In ayghri/i-have-adhd, the hook configuration resides in [hooks/hooks.json](https://github.com/ayghri/i-have-adhd/blob/main/hooks/hooks.json#L3-L15), where developers declare matcher patterns that determine when commands should execute.

The SessionStart hook triggers on multiple session lifecycle events: creation, resumption, clearing, and compaction. When a session matches the defined patterns, Claude Code automatically executes the associated command before the user begins interacting with the model.

The Hook Execution Logic

When triggered, the SessionStart hook runs [hooks/always-on.sh](https://github.com/ayghri/i-have-adhd/blob/main/hooks/always-on.sh#L1-L31), a POSIX shell script that implements conditional rule injection. The script performs four critical operations:

  1. Flag Verification: Checks for the existence of $CLAUDE_CONFIG_DIR/.i-have-adhd-always (defaulting to ~/.claude/.i-have-adhd-always) to determine if the user has opted into always-on mode.

  2. Path Resolution: Locates the skill's documentation by resolving the SKILL.md file path relative to the script's execution directory.

  3. Content Processing: Strips the YAML front-matter from [skills/i-have-adhd/SKILL.md](https://github.com/ayghri/i-have-adhd/blob/main/skills/i-have-adhd/SKILL.md), extracting only the actual rule set meant for the model.

  4. Message Injection: Prints a formatted system message declaring "ADHD MODE ACTIVE" and appending the full processed rule set, which Claude Code injects at the very beginning of the session context.

The script deliberately exits with status code 0 regardless of success or failure, ensuring that session creation never blocks due to hook errors.

Enabling and Managing the SessionStart Hook

Activating Always-On Mode

To enable automatic rule injection for every new session, create the opt-in flag file:

touch ~/.claude/.i-have-adhd-always

Once created, starting any new Claude Code session triggers the hook, which outputs a system message similar to:


ADHD MODE ACTIVE (always-on). The ruleset below applies to every response.
"stop adhd mode" turns it off for this session; delete /home/you/.claude/.i-have-adhd-always to turn always-on off for good.

<full rule set from SKILL.md>

Disabling for a Single Session

While the flag file remains in place for future sessions, users can temporarily disable the mode within an active conversation by typing:


stop adhd mode

This command instructs the model to ignore the injected rules for the current session only.

Running Without the Hook

If the flag file does not exist, the always-on.sh script exits silently and no rules are injected. Users can still manually invoke the skill using the slash command:


/i-have-adhd

This loads the same rule set from [SKILL.md](https://github.com/ayghri/i-have-adhd/blob/main/skills/i-have-adhd/SKILL.md) but only applies to the current session without automatic persistence.

Implementation Files and Architecture

The SessionStart hook implementation spans several key files in the repository:

  • hooks/hooks.json: Declares the hook trigger and binds it to the shell script execution.
  • hooks/always-on.sh: Contains the POSIX-compliant logic for conditional rule injection.
  • skills/i-have-adhd/SKILL.md: Stores the complete rule set that gets injected into sessions.
  • plugin.json: References the hook manifest and declares the plugin structure to Claude Code.

According to the source code in ayghri/i-have-adhd, this architecture ensures that the SessionStart hook remains lightweight and failure-resistant while providing seamless user experience for persistent configuration.

Summary

  • The SessionStart hook in Claude Code plugins runs automatically when sessions are created, resumed, cleared, or compacted.
  • Configuration occurs in hooks/hooks.json, which maps session events to executable commands.
  • The always-on.sh script demonstrates conditional execution based on user-opt-in flag files.
  • Hook scripts should always exit with status 0 to prevent blocking session initialization.
  • This pattern enables automatic system message injection, allowing plugins like i-have-adhd to preload guidelines without manual slash commands.

Frequently Asked Questions

How do I configure a SessionStart hook in my own Claude Code plugin?

Create a hooks directory containing a hooks.json file that defines a matcher pattern and the command to execute. Reference this manifest in your plugin.json file. When Claude Code detects a matching session event, it automatically runs the specified command, passing any necessary environment variables like $CLAUDE_CONFIG_DIR.

What happens if the SessionStart hook script fails or returns an error?

The i-have-adhd implementation ensures robustness by explicitly exiting with status code 0 at the end of always-on.sh. Claude Code expects hook scripts to handle their own error states, but a non-zero exit status could potentially block session creation depending on the client's error handling policies.

Can I use the SessionStart hook to inject custom system prompts or rules?

Yes. As demonstrated in the ayghri/i-have-adhd repository, the hook can print content to stdout that Claude Code treats as a system message. By printing formatted text from files like SKILL.md, you can dynamically inject custom instructions, personality settings, or operational guidelines at the start of every session.

Is the SessionStart hook triggered for existing sessions or only new ones?

According to the implementation, the hook fires on multiple session lifecycle events including creation, resumption, clearing, and compaction. This means the initialization logic runs not only when starting fresh conversations but also when restoring, clearing history, or compacting existing sessions.

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 →