[BUG] Plugin update/reinstall never refreshes installed cache for private git marketplaces — panel shows new version, but old code still runs
Description
Updating a plugin in a private/custom git-based marketplace (pushing a new commit + bumped version in .claude-plugin/plugin.json) is correctly picked up by the Plugins panel's displayed metadata (version number, description, "Last updated" timestamp), but the actual installed plugin cache is never refreshed — none of the normal update paths (toggle off/on, the panel's "reinstall" action from the ⋮ menu, or a full app restart) write any files to disk.
This means the panel can show a plugin as "up to date" at the new version while the code that actually runs is still the old version, with no visible indication of the mismatch.
Repro steps
- Have a plugin installed from a private git marketplace (
extraKnownMarketplacesinsettings.json, source typegit). - Locally, edit files in the marketplace's git checkout under
~/.claude/plugins/marketplaces/<marketplace>/plugins/<plugin>/, bumpversionin.claude-plugin/plugin.json, commit, andgit pushto the remote. - Open the Plugins panel for that plugin.
Observed:
- Panel immediately shows the new
version, the newdescriptiontext (I had changed both), and "Last updated: N minutes ago" matching the push time. - The "Update" button is greyed out / disabled, implying the plugin is already current.
- Check what's actually installed:
````
cat ~/.claude/plugins/installed_plugins.json # still shows old version + old gitCommitSha
ls ~/.claude/plugins/cache/<marketplace>/<plugin>/ # only the old version-numbered directory exists
- Try to force a refresh:
- Toggle the plugin off, then on again in the panel.
- Use the ⋮ menu → reinstall.
- Fully quit and restart the app.
Result: After each of these, installed_plugins.json's installedAt/lastUpdated/gitCommitSha fields and the cache directory contents are byte-for-byte unchanged (confirmed via stat — same mtimes as the original install, from hours earlier and before any of the above actions). The skill content (SKILL.md) actually loaded and executed by Claude Code in a real task also still reflects the old version — verified by grepping the cache copy for a string I added in the new version, which is absent.
Expected behavior
One of:
- The "Update" button should be enabled and clickable whenever the marketplace HEAD differs from the installed
gitCommitSha, and clicking it (or toggling off/on, or reinstalling) should actually re-fetch and unpack the new version into the cache and updateinstalled_plugins.json. - If the panel's displayed "Version"/"Last updated" reflect marketplace-HEAD metadata rather than the installed copy, that should be visually distinguished from the installed version, so users aren't misled into thinking they're running code they aren't.
Environment
- macOS (Darwin), Claude Code desktop
- Plugin source: private git marketplace (
extraKnownMarketplaces,source: git) - Confirmed via direct filesystem inspection (
installed_plugins.json,~/.claude/plugins/cache/...) rather than relying on the panel
Possibly related
- #83704 — "Desktop plugin stores desync: sessions load stale account-registry copies that shadow current CLI installs; settings Update checks the wrong store and Uninstall deletes from both" — matches my hypothesis that the panel is reading a different store than the actual install.
- #86700 — "claude plugin install refreshes the marketplace, sees a newer version, and still reports 'already installed' without upgrading"
- #45810 — "Marketplace update button is disabled/not pressable even when version is outdated"
- #72162 — "
/plugin marketplace update+/reload-pluginsdoes not pick up pushed plugin changes"
Those cover overlapping symptoms; filing separately because this repro is a fully offline-verifiable filesystem check (manifest + cache mtimes unchanged across three distinct update attempts) against a private git marketplace specifically, which may be a distinct code path from the official marketplace.