8000 Always-on hook misses the flag file when `CLAUDE_CODE_SUBPROCESS_ENV_SCRUB` removes `CLAUDE_CONFIG_DIR` · Issue #255 · ayghri/i-have-adhd · GitHub
[go: up one dir, main page]

Skip to content

Always-on hook misses the flag file when CLAUDE_CODE_SUBPROCESS_ENV_SCRUB removes CLAUDE_CONFIG_DIR #255

Open

Description

@pszypowicz

What happens

I keep my Claude Code config in ~/.config/claude with CLAUDE_CONFIG_DIR exported from my shell, and the flag file is at $CLAUDE_CONFIG_DIR/.i-have-adhd-always. The always-on SessionStart hook runs and exits 0 but prints nothing, so ADHD mode never loads.

I also set CLAUDE_CODE_SUBPROCESS_ENV_SCRUB=1 in the env block of settings.json. With that set, Claude Code leaves CLAUDE_CONFIG_DIR out of the hook's environment. always-on.mjs then falls back to ~/.claude/.i-have-adhd-always, doesn't find it there and exits quietly.

Steps to reproduce

  1. Export CLAUDE_CONFIG_DIR pointing anywhere other than ~/.claude.
  2. Add "CLAUDE_CODE_SUBPROCESS_ENV_SCRUB": "1" to env in $CLAUDE_CONFIG_DIR/settings.json.
  3. Install the plugin and run touch "$CLAUDE_CONFIG_DIR/.i-have-adhd-always".
  4. Start a session with claude -p "ok" --debug-file hook.log --include-hook-events --output-format stream-json --verbose.

The debug log shows that the hook ran:

Hooks: SessionStart:startup [node -e "..."] (plugin i-have-adhd@i-have-adhd) finished with status 0 (238ms)

Its hook_response event has "stdout": "" though. When I run the same command with --settings '{"env":{"CLAUDE_CODE_SUBPROCESS_ENV_SCRUB":"0"}}', CLAUDE_CONFIG_DIR shows up in the hook environment and the ruleset loads.

I saw this on Claude Code 2.1.296 on macOS with plugin 0.4.1. main still has the same lookup in always-on.mjs, always-on.sh and always-on.ps1.

Possible fix

I'm not sure what the cleanest fix is, so here is one idea. Installed plugins are copied to <config dir>/plugins/cache/..., so when CLAUDE_CONFIG_DIR is missing the hook could work out the config dir from its own install path before it falls back to ~/.claude:

function resolveClaudeDir(scriptDir) {
  if (process.env.CLAUDE_CONFIG_DIR) return process.env.CLAUDE_CONFIG_DIR;
  const marker = `${path.sep}plugins${path.sep}cache${path.sep}`;
  const i = scriptDir.indexOf(marker);
  if (i !== -1) return scriptDir.slice(0, i);
  return path.join(os.homedir(), ".claude");
}

This depends on how Claude Code lays out its plugin cache, which could change, and it doesn't help plugins loaded with --plugin-dir. CLAUDE_PLUGIN_DATA also survives the scrub and sits under the config dir, but using it depends on the layout in the same way. You may know of a better signal than either of these. Whichever way you go, the .sh and .ps1 fallbacks would need the same change.

This is the same kind of quiet failure as #129, where a missing environment variable makes the hook exit 0 with no output.

Workaround

A symlink at the default location works:

mkdir -p ~/.claude
ln -s "$CLAUDE_CONFIG_DIR/.i-have-adhd-always" ~/.claude/.i-have-adhd-always

Happy to open a PR if you'd like.

Activity

  1. added a commit that references this issue on Nov 2, 2026
    fef5949
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      0