feat(plugins): Plugin-scoped control over unprefixed skill aliases in autocomplete
Feature request: plugin-scoped control over unprefixed skill aliases in autocomplete
## Context
I maintain a plugin (xx) in a marketplace where every skill is intended to be invoked only via its namespaced form — /xx:add-project, /xx:help, /xx:migrate. The namespace is part of the plugin's public contract: it signals "this is a XX workflow command" and it's what the docs and CONTRIBUTING.md teach users to type.
## Observed behaviour
When I type /add in a session that has the plugin installed, autocomplete offers:
/add-project (xx) Register a XX project directory i.e. the unprefixed form of the skill name appears alongside the namespaced form. The bare form appears to be a convenience alias Claude Code adds when the skill name doesn't conflict with another installed skill.
## Problem
I can't turn this off. The docs describe two user-scoping frontmatter flags:
disable-model-invocation: true— blocks Claude from auto-invoking. Already set.
Doesn't affect autocomplete.
user-invocable: false— hides from the/menu, but the docs don't clarify whether
the namespaced form still works when it's set. Setting it risks making the skill entirely
unreachable, which defeats the purpose.
Neither gives me what I want: *"appear in autocomplete only under /xx:<skill>, never
under bare /<skill>."* There is also no plugin-level knob in plugin.json for this.
## Why this matters for plugin authors
- The namespace is a branding and discoverability signal. Showing skills unprefixed
breaks the /<plugin>:... mental model the docs themselves promote ("Plugin skills are
always namespaced to prevent conflicts").
- Autocomplete clutter: every plugin a user installs can add N bare aliases to the global
slash menu. With multiple plugins, this gets noisy fast.
- "No conflict today" is a fragile basis for aliasing. The bare form can start
conflicting later when another plugin ships a same-named skill — behaviour changes without
the user touching anything.
- For plugins that orchestrate internal workflows, users calling bare
/migrateinstead
of /xx:migrate is a footgun: they might invoke a different plugin's /migrate by
accident once conflicts arise.
## Proposed solutions
Any one of these would address the problem, in order of preference:
- Per-skill frontmatter flag:
namespace-only: true. Skill appears in autocomplete
only as /<plugin>:<skill>, never as bare /<skill>. Typing the bare form is either
rejected or falls through to non-plugin skills.
- Plugin-wide setting in
plugin.json:"namespaceOnly": true. Applies to every
skill in the plugin — simpler for plugin authors who want the policy uniform.
- Clarify
user-invocable: falsesemantics in the docs and guarantee that namespaced
invocation (/<plugin>:<skill>) still works when it's set. That turns it into a usable
workaround even without a new flag.
Happy to test a preview if any of this lands. Thanks!
This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗