fix(update): repair Claude plugin configs pinning a deleted brew node - #288
Merged
Merged
Conversation
Detect every plugin hooks.json/plugin.json naming a versioned Homebrew Cellar node that no longer exists, and repoint it at the keg's opt/ link, which brew keeps on the current version. Unfixable pins (no opt link, unwritable file) return 1 and leave the file as is. context-mode writes process.execPath into these files on Linux, so a `brew upgrade node` breaks every hook with "/bin/sh: 1: <path>: not found", and the plugin cannot heal itself because its MCP server starts from the same dead path. Refs mksglu/context-mode#1090 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014XqABrMmnsqj4xkck4VesT
A node upgrade outside `-t update` leaves the repair unrun, so doctor names each stale pin and points at `setup_env.sh -t update --brew-only`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014XqABrMmnsqj4xkck4VesT
`brew upgrade node` is what deletes the pinned Cellar node, so the repair runs in the same command: full update, --brew-only, and --claude-only (a plugin update extracts a fresh cache). A pin it cannot repair WARNs rather than failing the run. Refs mksglu/context-mode#1090 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014XqABrMmnsqj4xkck4VesT
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014XqABrMmnsqj4xkck4VesT
Every test set the override, so a typo in the production default would leave the feature inert while the suite stayed green. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014XqABrMmnsqj4xkck4VesT
The flag tests could not see the _run_all arm, so deleting it left the suite green on the most common invocation. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014XqABrMmnsqj4xkck4VesT
Name doctor as the backstop for node upgrades outside -t update, and record the pr-review advisories not fixed on this branch. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014XqABrMmnsqj4xkck4VesT
4 tasks done
github-actions Bot
pushed a commit
that referenced
this pull request
Sep 19, 2026
The comment enumerating record-then-overwrite sections, and the CLAUDE.md sentence counting them, both went stale the moment #288 added plugin-node without them. Point at the call sites instead of restating them. Also list the plugin node-path check in README's doctor row, and backlog the setup/developer path that never runs the repair. All three raised by code review on #288. Claude-Session: https://claude.ai/code/session_014XqABrMmnsqj4xkck4VesT Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
Summary
process.execPathinto its cachedhooks/hooks.jsonand.claude-plugin/plugin.jsonon Linux. Under linuxbrew that is a versionedCellar/node/<ver>/bin/node, sobrew upgrade nodedeletes it. Every Claude Code hook then fails with/bin/sh: 1: <path>: not found, and the context-mode MCP server does not start. The plugin cannot heal itself, because its repair only runs when that MCP server starts. Upstream: plugin.json mcpServers.command pinned to process.execPath has no liveness guard — and the MCP server cannot self-heal it mksglu/context-mode#1090, fix proposed in fix(hooks): persist a stable interpreter path, not a version-pinned snapshot (#1090) mksglu/context-mode#1183.claudepinned to 26.8.2 andworkstationto 26.4.0 (all six cached versions).studiowas clean, since upstream skips the rewrite on macOS.repair_plugin_node_paths(repoints each dead pin at the keg'sopt/link) and aplugin-nodesection in-t update. The section runs under a full update,--brew-onlyand--claude-only.doctorcheck that FAILs on each dead pin and names the remedy. It covers node upgrades that happen outside-t update.Changes
lib/helpers.sh:_claude_plugin_cache_dir,_plugin_stale_node_paths,repair_plugin_node_paths,_doctor_check_plugin_node_pathslib/workflows.sh,lib/update_summary.sh:plugin-nodesection and its_UPDATE_SECTION_ORDERentrytests/setup_env/plugin_node_paths.bats(20 tests),update_plugin_node.bats(7),unit.batsstubsCLAUDE.mdseam and doctor docs.docs/superpowers/README.md: 4 backlog rows for pr-review advisories not fixed here.Test Plan
make test: rc 0, 1972/1972 bats, 20 python OK, at 3074e6b; pre-push ran it againmake lint: rc 0ubuntu-latest): 26/26 before the final test was addedclaudeandworkstation: 4 reported, 4 repaired, 0 left, all valid JSONbash-coveragejob on this PRRisk
The repair rewrites JSON files in
~/.claude/plugins/cache, and only when a config names a versioned Homebrew node that no longer exists. The file set comes fromfind -type f, so symlinked files are not followed. A no-op run changes nothing.Related
mksglu/context-mode#1090, mksglu/context-mode#1183
🤖 Generated with Claude Code
https://claude.ai/code/session_014XqABrMmnsqj4xkck4VesT