Skip to content
Productivity
Hook

Hooks

What i-have-adhd runs automatically, and when. A hook is a command Claude Code fires at a fixed moment, without you asking for it.

From plugin
i-have-adhd
60k1 skill1 hook

Claude Code

> /plugin marketplace add ayghri/i-have-adhd
> /plugin install i-have-adhd@i-have-adhd

What fires, and when

SessionStart

Fires once when a session begins, and again after a context compaction. It is where a plugin sets up its environment, or restores state the compaction dropped.

  • Matchesstartup|resume|clear|compactnode -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(()=>{})"
Read hooks/hooks.json

Where it lives

  • hooks/always-on.mjsGitHub
    Read the script
    // SessionStart hook: injects the full i-have-adhd ruleset when the user has
    // opted in by creating $CLAUDE_CONFIG_DIR/.i-have-adhd-always (default ~/.claude).
    // Never blocks session start: any failure exits 0.
    //
    // Runs under Node so it works on macOS, Linux, and Windows. The shared Claude
    // Code/Codex hook launches this module from the plugin-root environment rather
    // than relying on platform-specific shell expansion for the script path.
    // Native sh and PowerShell implementations remain available as fallbacks.
    
    import fs from "node:fs";
    import os from "node:os";
    import path from "node:path";
    import { fileURLToPath } from "node:url";
    
    try {
      const claudeDir = process.env.CLAUDE_CONFIG_DIR || path.join(os.homedir(), ".claude");
      const flagPath = path.join(claudeDir, ".i-have-adhd-always");
    
      // Only fire when the user has opted in.
      if (!fs.existsSync(flagPath)) process.exit(0);
    
      // Resolve SKILL.md relative to this script's own location, not a trusted env var.
      const scriptDir = path.dirname(fileURLToPath(import.meta.url));
      const skillPath = path.join(scriptDir, "..", "skills", "i-have-adhd", "SKILL.md");
      if (!fs.existsSync(skillPath)) process.exit(0);
    
      // Strip a leading YAML frontmatter block (--- ... --- at the very top of file).
      const body = fs
        .readFileSync(skillPath, "utf8")
        .replace(
          /^---[^\S\r\n]*\r?\n[\s\S]*?\r?\n---[^\S\r\n]*(?:\r?\n|$)/,
          "",
        )
        .replace(/(?:\r?\n)+$/, "");
    
      process.stdout.write(
        "ADHD MODE ACTIVE (always-on). The ruleset below applies to every response. " +
          '"stop adhd mode" turns it off for this session; ' +
          `delete ${flagPath} to turn always-on off for good.\n\n${body}\n`,
      );
    } catch {
      // Never block session start.
      process.exit(0);
    }
    
  • hooks/always-on.ps1GitHub
    Read the script
    # SessionStart hook fallback for Windows PowerShell. Injects the full
    # i-have-adhd ruleset when the user has opted in by creating
    # $CLAUDE_CONFIG_DIR/.i-have-adhd-always (default ~/.claude).
    # Never blocks session start: any failure exits 0.
    
    try {
      $claudeDir = if ($env:CLAUDE_CONFIG_DIR) {
        $env:CLAUDE_CONFIG_DIR
      } else {
        Join-Path ([Environment]::GetFolderPath("UserProfile")) ".claude"
      }
      $flagPath = Join-Path $claudeDir ".i-have-adhd-always"
    
      if (-not (Test-Path -LiteralPath $flagPath -PathType Leaf)) {
        exit 0
      }
    
      $scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
      $skillPath = Join-Path $scriptDir "../skills/i-have-adhd/SKILL.md"
      if (-not (Test-Path -LiteralPath $skillPath -PathType Leaf)) {
        exit 0
      }
    
      $lines = [System.IO.File]::ReadAllLines($skillPath)
      $bodyStart = 0
    
      if ($lines.Length -gt 0 -and $lines[0] -match '^---\s*$') {
        # Only treat the block as frontmatter when the closing delimiter exists;
        # an unterminated fence is not frontmatter, so keep the whole file.
        for ($i = 1; $i -lt $lines.Length; $i++) {
          if ($lines[$i] -match '^---\s*$') {
            $bodyStart = $i + 1
            break
          }
        }
      }
    
      $body = if ($bodyStart -lt $lines.Length) {
        [string]::Join([Environment]::NewLine, $lines[$bodyStart..($lines.Length - 1)])
      } else {
        ""
      }
    
      $banner = 'ADHD MODE ACTIVE (always-on). The ruleset below applies to every response. ' +
        '"stop adhd mode" turns it off for this session; delete '
      [Console]::Out.Write($banner + $flagPath + " to turn always-on off for good.`n`n" + $body + "`n")
    } catch {
      # Never block session start.
      exit 0
    }
    
  • hooks/always-on.shGitHub
    Read the script
    #!/usr/bin/env sh
    # SessionStart hook: injects the full i-have-adhd ruleset when the user has
    # opted in by creating $CLAUDE_CONFIG_DIR/.i-have-adhd-always (default ~/.claude).
    # Never blocks session start: any failure exits 0.
    #
    # POSIX fallback for environments where the default Node hook cannot run. It
    # works with sh on macOS/Linux and Git Bash on Windows without a Node install.
    
    claude_dir="${CLAUDE_CONFIG_DIR:-$HOME/.claude}"
    flag_path="$claude_dir/.i-have-adhd-always"
    
    # Only fire when the user has opted in.
    [ -f "$flag_path" ] || exit 0
    
    # $0 is the absolute script path substituted into hooks.json by Claude Code,
    # so resolve SKILL.md relative to it instead of trusting an exported env var.
    script_dir=$(dirname -- "$0")
    skill_path="$script_dir/../skills/i-have-adhd/SKILL.md"
    [ -f "$skill_path" ] || exit 0
    
    # Strip a leading YAML frontmatter block (--- ... --- at the very top of file).
    # An unterminated fence is not frontmatter, so the whole file is kept unless the
    # closing delimiter exists (two passes; matches the Node and PowerShell hooks).
    body=$(awk '
      NR == FNR {
        if (NR == 1 && $0 ~ /^---[[:space:]]*$/) { in_fm = 1; next }
        if (in_fm && $0 ~ /^---[[:space:]]*$/)   { in_fm = 0; closed = 1 }
        next
      }
      FNR == 1 { strip = closed }
      strip && FNR == 1 && $0 ~ /^---[[:space:]]*$/ { skipping = 1; next }
      skipping && $0 ~ /^---[[:space:]]*$/          { skipping = 0; next }
      !skipping { print }
    ' "$skill_path" "$skill_path") || exit 0
    
    printf 'ADHD MODE ACTIVE (always-on). The ruleset below applies to every response. "stop adhd mode" turns it off for this session; delete %s to turn always-on off for good.\n\n%s\n' \
      "$flag_path" "$body"
    

Read the script before you install anything that runs on your machine. This is the one part of a plugin that acts without being asked.

@ayghri
Ships withi-have-adhd

A skill to stop your coding agent from burying the answer. ADHD-friendly output.

Stars on GitHub

Momentum

stars in total
59.7k
Star history of ayghri/i-have-adhd on GitHub, a chart by star-history.com

More plugins that ship hooks.

pua

pua

A Claude Code plugin that makes the assistant work harder when it stalls or repeats failures. It adds pressure-style coaching, plus skills for workplace reminders and senior engineer, CTO and team-lead modes for planning and execution.

12 skills+320k
@tanweai@tanweai
Install Plugin
claude-obsidian

claude-obsidian

Turns the sources you read, such as papers, articles and transcripts, into a linked wiki of Markdown notes in Obsidian. Claude keeps sources and citations so every summary can be traced back to its origin.

15 skills+216k
@agricidaniel@agricidaniel
Install Plugin
obsidian-second-brain

obsidian-second-brain

Gives Claude Code a persistent second brain stored as plain markdown in an Obsidian vault. Notes rewrite themselves as new sources arrive, and scheduled agents handle research synthesis and note capture.

1 skill+25.3k
@eugeniughelbur@eugeniughelbur
Install Plugin
arscontexta

arscontexta

A Claude Code plugin that builds a personal knowledge system through conversation, with skills for adding knowledge domains, checking vault health, getting methodology guidance, and evolving the system over time.

10 skills+23.5k
@agenticnotetaking@agenticnotetaking
Install Plugin
pro-workflow

pro-workflow

A Claude Code workflow plugin that learns from your corrections and keeps a self-correcting memory across sessions. It adds skills for agent teams, parallel worktree batch changes, bug capture as GitHub issues, project auto-setup and context compaction.

41 skills+32.9k
@rohitg00@rohitg00
Install Plugin
engram

engram

Helps you learn any topic with a first-principles curriculum, guided tutoring, and spaced review that schedules free-recall practice. Includes coaching for retention stats and study strategy.

3 skills+21.5k
@nagisanzenin@nagisanzenin
Install Plugin
hey

hey

A command line tool for HEY that lets you read and send email, manage contacts, labels, calendars, todos, habits, time tracking and journal entries from the terminal or from your coding agent.

1 skill1 hook423
@basecamp@basecamp
Install Plugin
basecamp-cli

basecamp-cli

Lets you manage Basecamp projects, todos, cards, messages, files and schedules from your terminal or from Claude Code, so you stop switching to the web app for routine updates.

3 skills4 hooks294
@basecamp@basecamp
Install Plugin

Questions about the hooks in i-have-adhd.

Which coding agents can use the hooks in i-have-adhd?
The hooks in i-have-adhd install in Claude Code and Cursor: each runs Claude Code hooks from .claude/settings.json, so copy the hooks there.