Plugin install scope in installed_plugins.json doesn't match actual accessibility via enabledPlugins

Resolved 💬 2 comments Opened Feb 15, 2026 by danieldeusing Closed Feb 15, 2026

Summary

When a plugin is installed via an npx registry with a specific scope (project or local) and projectPath, the plugin is recorded in ~/.claude/plugins/installed_plugins.json with that scope restriction. However, the plugin files are stored globally in ~/.claude/plugins/cache/, and the plugin is added to enabledPlugins in ~/.claude/settings.json — which makes it accessible from all projects, regardless of the recorded scope.

Current Behavior

1. Plugin storage is always global

All plugin files are stored in ~/.claude/plugins/cache/<registry>/<plugin-name>/<hash>/, regardless of the install scope. For example:

~/.claude/plugins/cache/claude-plugins-official/frontend-design/2cd88e7947b7/skills/frontend-design/SKILL.md

2. installed_plugins.json records scope + projectPath

{
  "frontend-design@claude-plugins-official": {
    "name": "frontend-design",
    "registry": "claude-plugins-official",
    "scope": "local",
    "projectPath": "/Users/user/Work/project-a/folder",
    "version": "..."
  }
}

This suggests the plugin should only be active for project-a/folder when scope is local.

3. settings.json enabledPlugins overrides scope

{
  "enabledPlugins": {
    "frontend-design": true
  }
}

This makes the plugin callable from any project directory, contradicting the scope recorded in installed_plugins.json.

4. Claude CLI confirms global access

Running claude from any project directory allows calling skills from the "local"-scoped plugin — it works from /Users/user/Work/project-b/, /Users/user/Work/project-c/, etc., not just from the recorded projectPath.

Expected Behavior

One of:

  • Option A: If a plugin is installed with scope: "local" or scope: "project", it should only be accessible from the matching projectPath. The enabledPlugins entry should either not be created for scoped plugins, or should include scope metadata.
  • Option B: If enabledPlugins is meant to make plugins globally accessible, then installed_plugins.json should not record misleading scope/projectPath values, or the scope should be set to "user" for globally-enabled plugins.

Impact

Third-party tools (like configuration UIs) that read installed_plugins.json to determine which plugins are active for a given project cannot rely on the scope/projectPath fields, since the actual accessibility is determined by enabledPlugins in settings.json. This creates a discrepancy between "where the plugin was installed from" and "where the plugin is actually usable."

Reproduction

  1. Navigate to a project directory, e.g. /path/to/project-a
  2. Install a plugin with local scope: claude plugin add frontend-design --scope local
  3. Verify installed_plugins.json records scope: "local" and projectPath: "/path/to/project-a"
  4. Navigate to a completely different project: cd /path/to/project-b
  5. The plugin's skills are still callable from project-b

Environment

  • Claude Code CLI
  • macOS / Linux
  • Plugin system v2 format (installed_plugins.json)

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗