Conversation
…napshot (mksglu#1090) normalizeHooksJsonOnly/normalizeHooksOnStartup bake process.execPath verbatim into hooks.json commands and plugin.json's mcpServers.command. On a version manager (Homebrew Cellar, nvm, asdf, mise) that path is a versioned snapshot that the next upgrade deletes. For mcpServers.command specifically there is no self-heal once that happens: the process that would re-run this normalization is the MCP server itself, which is exactly what fails to spawn. Add resolveStableInterpreterPath(): before persisting, prefer a same-named PATH entry whose realpath matches execPath's realpath and whose own path is not itself version-pinned (e.g. Homebrew's unversioned <prefix>/bin/node symlink). Falls back to execPath unchanged when no such candidate exists, preserving PR mksglu#582's nvm/mise fix (bare "node" is not reliably on PATH for those managers). Wired into both normalizeHooksJsonOnly (hooks.json) and the plugin.json branch of normalizeHooksOnStartup, so the same fix also closes the write-time version of the hooks.json variant of this defect, not only the plugin.json case mksglu#1090 reports. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014XqABrMmnsqj4xkck4VesT
5 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1090.
Problem
normalizeHooksJsonOnlyandnormalizeHooksOnStartupwriteprocess.execPathintohooks/hooks.jsonand.claude-plugin/plugin.json(mcpServers.command). Under Homebrew/linuxbrew, and other version managers, that is a versioned path such as/home/linuxbrew/.linuxbrew/Cellar/node/26.8.2/bin/node, which the nextbrew upgrade noderemoves. Every hook then fails with/bin/sh: 1: <path>: not found, and the MCP server cannot start, so it can never run the normalization that would repair it.Change
Adds
resolveStableInterpreterPath(execPath)tohooks/normalize-hooks.mjsand uses it in both places an interpreter path is written. IfexecPathsits under a version-numbered directory, it looks onPATHfor a same-named binary whoserealpathmatchesexecPath's and whose own path is not version-numbered, such as Homebrew's<prefix>/bin/node, and writes that instead. If there is no such candidate (plain nvm/asdf),execPathis written unchanged, so the nvm/mise behaviour from #582 is kept.Scope
This prevents new version-pinned writes. It does not rewrite a cache that already holds one, because
needsHookNormalization()only fires on the placeholder or a stale cache-version segment. Existing installs therefore pick up the fix when a plugin update extracts a new version. If you'd rather also convert an existing live versioned pin at MCP start, a trigger inneedsHookNormalization()would do it; I kept it out to keep this change small.Testing
tests/hooks/windows-hooks-normalization.test.ts. Five coverresolveStableInterpreterPath: stable sibling, not version-pinned, no stable sibling, a same-named binary with a different realpath, and a version-pinnedPATHentry ahead of the stable one. Two go end to end throughnormalizeHooksOnStartupwith a real tmpdir and symlink fixture.main(7 failed of 23) and pass with the change (23 of 23).npx vitest run: 4715 passed, 34 skipped.npm run typecheckandnpm run buildare clean.Note: CONTRIBUTING.md says to branch from
next, butorigin/nextwas last updated 2026-08-12 and lacks recent changes tonormalize-hooks.mjs, so this is based onmain.🤖 Generated with Claude Code
https://claude.ai/code/session_014XqABrMmnsqj4xkck4VesT