Local plugin commands not discovered despite correct structure

Resolved 💬 6 comments Opened Mar 14, 2026 by fkhawajagh Closed Apr 13, 2026

Bug Description

A locally registered plugin's /tool-stats command is not discoverable via slash commands in Claude Code, despite the plugin structure matching working plugins exactly.

The plugin's hooks (PreToolUse, PostToolUse, Stop) all work correctly — data is being collected into the SQLite database. Only the command discovery is broken.

Environment

  • Claude Code version: 2.1.76
  • OS: macOS (Darwin 24.6.0)
  • Shell: zsh

Plugin Structure

~/.claude/hooks/tool-tracker/
├── .claude-plugin/
│   ├── plugin.json
│   └── marketplace.json
├── commands/
│   └── tool-stats.md          ← not discovered
├── tool_tracker.py            ← hooks work fine
├── tool_tracker_report.py
├── tool_tracker_classify.py
├── tool_classifications.json
├── tool_tracker.db
└── tool_tracker.log

plugin.json

{
  "name": "tool-tracker",
  "description": "Track and report on tool usage across Claude Code sessions",
  "version": "1.0.0"
}

marketplace.json

{
  "name": "tool-tracker-local",
  "description": "Tool usage tracking and reporting for Claude Code sessions",
  "plugins": [
    {
      "name": "tool-tracker",
      "description": "Track and report on tool usage across Claude Code sessions",
      "version": "1.0.0",
      "source": "./"
    }
  ]
}

commands/tool-stats.md (frontmatter)

---
allowed-tools: Bash(python3 ~/.claude/hooks/tool-tracker/tool_tracker_report.py:*)
description: Show tool usage statistics from the tracker database
---

settings.json (relevant sections)

{
  "enabledPlugins": {
    "tool-tracker@tool-tracker-local": true
  },
  "extraKnownMarketplaces": {
    "tool-tracker-local": {
      "source": {
        "source": "directory",
        "path": "/Users/farouk/.claude/hooks/tool-tracker"
      }
    }
  }
}

Comparison with Working Plugins

Compared against two working plugins with the same local marketplace pattern:

| Aspect | superpowers (works) | tool-tracker (broken) |
|--------|--------------------|-----------------------|
| marketplace.json location | .claude-plugin/ | .claude-plugin/ |
| plugin.json location | .claude-plugin/ | .claude-plugin/ |
| source in marketplace | "./" | "./" |
| commands/ directory | commands/ at root | commands/ at root |
| command frontmatter | has description | has description |
| registration in settings | enabledPlugins + extraKnownMarketplaces | enabledPlugins + extraKnownMarketplaces |

The structure is identical. Hooks from the plugin execute correctly (PreToolUse, PostToolUse, Stop), confirming the plugin itself is loaded. Only command discovery fails.

Steps to Reproduce

  1. Create a local plugin with the structure above
  2. Register it in settings.json under enabledPlugins and extraKnownMarketplaces
  3. Start a new Claude Code session
  4. Type /tool-stats — command is not found
  5. Check available skills list — tool-tracker:tool-stats does not appear

Expected Behavior

/tool-stats should appear as an available command, similar to how /brainstorm works from the superpowers plugin.

Actual Behavior

The command is not discovered. Typing /tool-stats returns "Unknown skill: tool-stats". The plugin's hooks continue to work correctly.

View original on GitHub ↗

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