[Bug]: Same-name skills from different sources collide and can invoke the wrong skill
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 23k
- Forks
- 5.9k
- Avg merge
- 11h 14m
- Merged PRs (30d)
- 357
Description
Problem
Two unrelated skills named code-review collide in T3 Code: Matt Pocock's locally installed skill (~/.agents/skills/code-review/SKILL.md) and an official plugin's skill with the same name. Selecting/referencing code-review invoked the official skill instead of Matt's. We worked around it by renaming Matt's skill to standards-and-spec-review.
Reproduction
- Install two enabled skills with identical
name: code-reviewbut different sources and instructions, one personal and one plugin-provided. - Open the Codex
$skill picker. - Try to select and invoke the personal skill independently of the plugin skill.
Expected
Distinct sources remain distinguishable and independently selectable. The selected skill's exact identity/path is preserved through dispatch, so the picker cannot silently invoke another same-name skill.
Actual and code evidence
Checked local main at c52b8d96e4b34201f19b5e5bb12c6b2a77bfaa9a:
packages/client-runtime/src/providerSkills.ts:32:dedupeProviderSkillsByNameretains only the first trimmed, case-insensitive name, ignoring source/path.apps/web/src/components/chat/ChatComposer.tsx:2931: selection inserts only$${item.skill.name}.apps/server/src/provider/Layers/CodexSessionRuntime.ts:626: the prompt is sent as a text input, without a structured skill input binding the selected path.
A direct Node invocation of the real deduplication function confirmed that [plugin, personal] retains only the plugin, [personal, plugin] retains only the personal skill, and giving the personal skill a different name retains both. This verifies the picker collision; it does not imply a hardcoded preference for official plugins in the provider.
Related
- #8043 fixed duplicate menu IDs/highlighting by deduplicating on name, but assumes same-name definitions are interchangeable.
- #6095 reports missing explicit Codex skill binding.
This report specifically concerns distinct skills from different sources sharing a name. Please preserve stable unique menu identity as well as the selected source when resolving this.
Provider scope
The fix should apply to all T3 Code providers: Codex, Claude Code, Cursor, Grok, OpenCode, and Antigravity. The original reproduction used Codex, but both source-aware discovery/selection and exact-source dispatch must be preserved across providers and web/desktop/mobile clients.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with packages/client-runtime/src/providerSkills.ts and its dedupeProviderSkillsByName behavior, then trace selection in apps/web/src/components/chat/ChatComposer.tsx and dispatch in apps/server/src/provider/Layers/CodexSessionRuntime.ts. Reproduce the direct Node deduplication check with same-name skills from different sources; done when distinct source/path identities remain selectable and the selected source is preserved through dispatch across the listed providers and clients.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- full-stack, tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 58/100