Skip to content

[BUG] Plugin skills/ don't register as slash commands when plugin is loaded via project-local extraKnownMarketplaces (file:// source) — docs and implementation disagree #57737

Description

@thewoolleyman

Summary

A Claude Code plugin loaded into a project via extraKnownMarketplaces + enabledPlugins in .claude/settings.json (or ~/.claude/settings.json) shows as ✔ enabled in /plugin, and its skills load as Agent Skills (model can invoke via the Skill tool). But the plugin's skills do NOT appear in / slash-command autocomplete, regardless of whether the enablement is at project scope or user scope.

Adding a parallel commands/<name>.md directory at the plugin root makes the slash commands appear. So commands/ works; skills/ alone doesn't — exactly the inversion of what the docs describe.

This consolidates evidence from multiple related (some closed, some open) issues that have not been individually resolved.

Reproduction

.claude/plugins/my-plugin/
├── .claude-plugin/
│   ├── plugin.json        # {"name":"my-plugin","version":"0.1.0","description":"..."}
│   └── marketplace.json   # local marketplace pointing at ./.claude-plugin
└── skills/
    └── hello/
        └── SKILL.md       # frontmatter has name: hello, description: ...

.claude/settings.json:

{
  "extraKnownMarketplaces": {
    "my-plugin-local": {
      "source": {
        "source": "file",
        "path": "./.claude/plugins/my-plugin/.claude-plugin/marketplace.json"
      }
    }
  },
  "enabledPlugins": {
    "my-plugin@my-plugin-local": true
  }
}

Then in the CLI:

  • claude plugin listStatus: ✔ enabled
  • /reload-plugins → reports skill count that EXCLUDES this plugin's skills (verified by counting against other loaded plugins)
  • Typing /my-plugin:hello (or /hello) in autocomplete → no match
  • Adding commands/hello.md with frontmatter + body → autocomplete immediately finds it after /reload-plugins

Tested with both project-scope (.claude/settings.json) and user-scope (~/.claude/settings.json) enablement — same result either way. Scope is not the variable.

Documentation contradicting the observed behavior

From Skills:

Custom commands have been merged into skills. A file at .claude/commands/deploy.md and a skill at .claude/skills/deploy/SKILL.md both create /deploy and work the same way.

From Plugins reference:

Plugins add skills to Claude Code, creating /name shortcuts that you or Claude can invoke.
Location: skills/ or commands/ directory in plugin root
Skills and commands are automatically discovered when the plugin is installed

Per docs, skills/ alone should produce slash commands. It doesn't, for project-local marketplace plugins.

Related closed issues (the underlying bug recurs)

Related open issues (different facets of the same problem space)

Ask

Either:

  1. Fix implementation to match docs — make skills/<name>/SKILL.md register as /<plugin-name>:<skill-name> slash commands when the plugin is loaded via project-local extraKnownMarketplaces (and any other path where the plugin is currently enabled but its skills aren't surfacing).
  2. Update docs to clarify that for project-local marketplace plugins, skills/ alone is insufficient and commands/<name>.md files are required for slash-command exposure.

Either resolves the contradiction. Option 1 is preferred — it matches the design direction implied by "custom commands have been merged into skills."

Workaround (currently)

Author a parallel commands/<name>.md for each skill, with frontmatter matching what the SKILL.md would have provided (description, allowed-tools, etc.) and a body that delegates to the corresponding SKILL.md. Maintainable but redundant — duplicates frontmatter and adds drift risk between SKILL.md and command.md.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions