Summary
The /plugin TUI is the most visible way users interact with plugins, but its uninstall flow is inconsistent with the working claude plugin uninstall CLI. As a user I have 32 plugins installed at user scope, and no combination of actions inside /plugin actually removes one — the commands and skills keep reappearing after restart. Only dropping to the shell and running claude plugin uninstall <name>@<marketplace> actually removes the plugin.
The TUI is also confusing because "Uninstall" and "Disable" appear to be collapsed into a single "remove at user scope" action, which is not how the state actually works.
Environment
- Claude Code CLI (latest as of 2026-04-23)
- macOS (Darwin 25.2.0)
- Single-user machine, all plugins installed at
scope: "user"
- 32 plugins from 5 marketplaces registered in
~/.claude/plugins/installed_plugins.json
Steps to reproduce
- Install any plugin, e.g.
claude plugin install searchfit-seo@claude-plugins-official
- Open
/plugin in an interactive session
- Navigate to the plugin and choose the remove option
- Exit and restart Claude Code
- Type
/ — the plugin's commands are still present; the skill list at session start still includes its skills
Expected
- A clear, distinct "Uninstall" action in
/plugin that:
- Removes the entry from
~/.claude/plugins/installed_plugins.json
- Removes the
enabledPlugins flag from both ~/.claude/settings.json and ~/.claude/settings.local.json
- Deletes the cached directory at
~/.claude/plugins/cache/<marketplace>/<plugin>/
- Refreshes the session's skill/command registry (or tells the user a restart is required)
- A separate, clearly labeled "Disable" action that only toggles the enabled flag.
Actual
- The TUI shows what appears to be a single "remove at user scope" action.
- After using it, at least one of the four state locations (registry, cache, user-scope flag, local-scope flag) remains dirty, so the plugin re-appears on the next session.
- The
enabledPlugins entry in settings.local.json is especially easy to miss — a plugin disabled at user scope but enabled in settings.local.json silently re-enables itself.
- There is no in-TUI indication that a restart is required, so the uninstall looks like it silently failed even when it partially succeeded.
Workaround
Run this from the shell instead — it works correctly every time:
```bash
claude plugin uninstall @
```
Example: `claude plugin uninstall searchfit-seo@claude-plugins-official`
This makes the TUI/CLI asymmetry the core bug: the CLI already does the right thing, the TUI should call the same code path.
Proposed fix
- In `/plugin`, split "Uninstall" and "Disable" into two separate actions with distinct labels.
- Route "Uninstall" through the same code path as `claude plugin uninstall`, including the cache deletion and clearing of `enabledPlugins` flags in both `settings.json` and `settings.local.json`.
- After uninstall, either hot-reload the session's skill/command registry, or surface a banner: `Uninstalled . Restart Claude Code to clear loaded skills and commands.`
- Consider surfacing `settings.local.json` overrides in the TUI — they're currently invisible and cause the "why did this plugin come back?" class of bug.
Why this matters
Plugins are now the main surface for adding skills and commands, and users install a lot of them. When uninstall doesn't work reliably, the skill list becomes permanently cluttered and users can't trust the UI to manage their own setup. The CLI proves the underlying system works — this is purely a TUI/UX gap.
Summary
The
/pluginTUI is the most visible way users interact with plugins, but its uninstall flow is inconsistent with the workingclaude plugin uninstallCLI. As a user I have 32 plugins installed at user scope, and no combination of actions inside/pluginactually removes one — the commands and skills keep reappearing after restart. Only dropping to the shell and runningclaude plugin uninstall <name>@<marketplace>actually removes the plugin.The TUI is also confusing because "Uninstall" and "Disable" appear to be collapsed into a single "remove at user scope" action, which is not how the state actually works.
Environment
scope: "user"~/.claude/plugins/installed_plugins.jsonSteps to reproduce
claude plugin install searchfit-seo@claude-plugins-official/pluginin an interactive session/— the plugin's commands are still present; the skill list at session start still includes its skillsExpected
/pluginthat:~/.claude/plugins/installed_plugins.jsonenabledPluginsflag from both~/.claude/settings.jsonand~/.claude/settings.local.json~/.claude/plugins/cache/<marketplace>/<plugin>/Actual
enabledPluginsentry insettings.local.jsonis especially easy to miss — a plugin disabled at user scope but enabled insettings.local.jsonsilently re-enables itself.Workaround
Run this from the shell instead — it works correctly every time:
```bash
claude plugin uninstall @
```
Example: `claude plugin uninstall searchfit-seo@claude-plugins-official`
This makes the TUI/CLI asymmetry the core bug: the CLI already does the right thing, the TUI should call the same code path.
Proposed fix
Why this matters
Plugins are now the main surface for adding skills and commands, and users install a lot of them. When uninstall doesn't work reliably, the skill list becomes permanently cluttered and users can't trust the UI to manage their own setup. The CLI proves the underlying system works — this is purely a TUI/UX gap.