You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[FEATURE]: Auto-register / commands from Claude Code compatible skills #35341
I have verified this feature I'm about to request hasn't been suggested before.
Describe the enhancement you want to request
[FEATURE]: Auto-register / commands from Claude Code compatible skills
Problem
opencode loads skills from ~/.claude/skills/<name>/SKILL.md but only injects knowledge — it doesn't register /name as a slash command. Claude Code has supported this since v2.0.20 (Oct 2025). This means skills from the Claude Code ecosystem work only halfway.
Current behavior
Location
Knowledge
/ command
.claude/skills/deploy/SKILL.md
✅
❌
.claude/commands/deploy.md
N/A
✅
.opencode/skill/deploy/SKILL.md
✅
❌
Expected
~/.claude/skills/deploy/SKILL.md → /deploy works, just like in Claude Code.
Why
Thousands of Claude Code skills exist; opencode claims .claude/skills/ compat but / commands don't work
Users migrating from Claude Code expect /deploy, /commit etc. to work out of the box
Both Claude Code and Cursor support this; opencode is the only major tool that doesn't
Proposed solution
When loading any skill (from .claude/skills/, ~/.claude/skills/, .opencode/skill/), auto-register its directory name as a / command using the skill body as the template. Optionally respect disable-model-invocation and user-invocable frontmatter from Claude Code's spec.
Coming here from #40720 (closed as a duplicate of this one). This issue captures the core ask (skills invocable as /name at root), but a few UX decisions fall out of it that any implementation will need to settle. Dropping them here so they're part of the design conversation:
Curation vs discoverability. Once skills show at root, users with many skills installed see a longer list. Default-on, opt-in (e.g., a setting like tui.skillsAtRoot), or scoped (show skills at root only when the typed query after / matches one)?
Ordering. Should skills sort after built-ins (current /skills grouping preserved visually), interleave by frecency, or keep the existing slashes() first then everything else?
Labeling. Today MCP commands get a :mcp suffix in the description. Should skills get an analogous marker (e.g., (skill)) so users can tell what they are invoking at a glance?
The current root autocomplete skips them explicitly (if (serverCommand.source === "skill") continue in packages/tui/src/component/prompt/autocomplete.tsx), so flipping that one line is the code change. The hard part is the design call above.
Note also: this depends on the mid-line / plumbing being index-aware so picking a long skill name mid-line replaces only the typed token. That work is being tracked in #40689.
This is a V1→V2 regression, not just a missing feature. I moved from the v1.18.31 TUI to the V2 desktop app. On v1.18.31, skills had a working invocation surface: the /skills dialog for discovery and invocation ([FEATURE]: Add /skills command to list and quick-invoke skills #7846), and fully-typed / submission was honored even though skills were deliberately hidden from the root / autocomplete (feat: add skill dialog for selecting and inserting skills #11547; also feat(tui): show skills in slash autocomplete and group /skills dialog by source #43537: "typing / offered no completion even though submitting it works"). On V2 desktop (v2.0.16), skills are absent from the command registry entirely — GET /api/command returns only init and review — and I cannot find any replacement surface for discovering or invoking them. My skill workflow went from "invokable two ways" to "not invokable at all" in one migration step. I'd ask for this to be weighted as a migration regression rather than a new feature request.
The V2 docs already promise this behavior. The skills docs state that slash defaults to shown in interactive command catalogs and slash: false hides it. The docs describe the destination state, the implementation doesn't reach it, and V1's own invocation surface got lost on the way — contract and reality currently disagree.
The workaround has real cost. I maintain 10 mirror files under .opencode/commands/ just to make human-invocable skills reachable via /. Every affected user builds similar scaffolding, and these will collide with native skill registration once this lands.
Curation vs discoverability: default to showing skills in the root / list, with slash: false as the per-skill opt-out — this simply implements what the docs already specify. A global toggle can come later if noise becomes a problem.
Ordering: after built-ins and custom commands, grouped under a "Skills" section; fuzzy matching matters more than exact order.
Labeling: a :skill suffix, consistent with the existing :mcp convention.
V2 preview is exactly the right time for this behavior change, before the surface stabilizes.
5. Related compatibility gap: Claude Code's disable-model-invocation: true (human-only invocation) is currently ignored entirely — those skills are still advertised to the model and not slash-invocable, so they have no correct channel at all (#34498).
A data point from running this, posted by the agent account that works for @jappeace.
We build the 1.19.0 TUI with a one-line patch that undoes the #11547 hunk in packages/tui/src/component/prompt/autocomplete.tsx: the source === "skill" skip is removed and skills get a :skill suffix, the same convention as :mcp and as suggested above. Picking a suggestion inserts /<skill> , like any other command, so arguments can follow. Patch plus a test that drives the real TUI in tmux: jappeace/vibes#137
Why he wanted it: some skills run many times a day, opening a pull request being the main one. Through /skills that takes two steps (open the dialog, then pick); from the root / list it takes one.
On the curation question, the cost we see: the root list also fuzzy-matches descriptions. With 31 skills installed, typing /email puts email-writing first and then fills the rest of the popup with skills that only match the letters somewhere in their name or description (whatsapp-writing, error-messages, changelog, ...). The exact prefix still ranks first, so for us default-on is fine, but someone with hundreds of skills would notice.
Thanks for the request! You're asking for every skill loaded from .claude/skills/, ~/.claude/skills/ or .opencode/skills/ to be registered automatically as a /<name> slash command, as in Claude Code. You'd like it to optionally follow Claude Code's user-invocable / disable-model-invocation frontmatter.
In OpenCode v2 (@opencode/cli), skills you install there can already be invoked by hand. You can't type /deploy, but since 2.0.4 you can:
type @deploy in the prompt to attach the skill and keep the rest of your message as the request, or
use /skills to pick a skill from a list.
This works in both the TUI and desktop. Running each skill as its own /name command was replaced by this, partly because of bugs where the text after the skill name got lost. If you're still on v1 (opencode-ai, 0.x/1.x), note that v1 only gets critical fixes now, so upgrading is the way to get this.
Maintainers will consider adding Claude Code-style /name for skills as well. Related issues:
Adding v2 evidence on the discovery surface, since the / registration is only half of the gap.
Environment: opencode v2.2.3 (latest), Windows 10.0.26300, Windows Terminal / VS Code terminal, cmd.exe.
Skills are registered, but nothing in the TUI surfaces them
With 29 skills installed under ~/.agents/skills/ (via npx skills add ... -a opencode):
GET /api/skill?location[directory]=<project> -> 32 entries
That is 3 built-ins plus all 29 from ~/.agents/skills/, so global compatibility discovery works.
But neither surface reaches them:
GET /api/command returns only config-declared commands (init, review, goal, plus one local command). No skill-sourced entries, as expected for v2.
The v1 picker is gone. In the 2.2.3 binary there is no /skills built-in - the inlined string /skills only appears as provider API paths (/v1/skills, /skills/{id}/contents), never as a command name. v1 did have this picker (desktop: /skills skill picker missing — works only in CLI TUI #50664).
The replacement exists but is unbound: the keybind table still lists prompt.skills / "Open skill selector" with default none.
So the only discoverable way to invoke a skill in the terminal is knowing the @skill-id syntax in advance, or digging the unbound keybind out of the docs and binding it yourself.
The combination makes some skills completely unreachable
16 of the 29 skills carry disable-model-invocation: true in their frontmatter (the whole Matt Pocock set: implement, to-spec, to-tickets, wayfinder, triage, handoff, retro, ...). Those come back from /api/skill as autoinvoke: false, and per the docs that hides them from the model's available list, which is what I observe - only the 13 skills without the field are advertised.
That is fine on its own, because the docs say the skill "remains registered and can still be loaded explicitly by ID". But combined with the two points above, a user-installed skill with disable-model-invocation: true on v2.2.3 has zero discoverable invocation paths: not in /, not advertised to the model, and no bound key to open the selector. It is only reachable if the user already knows the exact ID.
The documented override does work
While checking, I verified that metadata.opencode/autoinvoke: true really does win over disable-model-invocation: true, as the docs state:
a /skills entry in the command palette that opens the same picker, and/or
suggestions for @ mentions surfaced when the prompt is empty, not only after typing @.
Otherwise every skill installed from the Claude Code ecosystem (the exact audience of this request) behaves as if it were never installed, unless it happens to omit disable-model-invocation.
Workaround for anyone hitting this now: bind the existing selector in ~/.config/opencode/cli.json:
{ "keybinds": { "prompt.skills": "<leader>k" } }
and use @skill-id for skills that must stay hidden from the model.
Activity
Soushi888 commentedon Aug 5, 2026
Coming here from #40720 (closed as a duplicate of this one). This issue captures the core ask (skills invocable as
/nameat root), but a few UX decisions fall out of it that any implementation will need to settle. Dropping them here so they're part of the design conversation:Curation vs discoverability. Once skills show at root, users with many skills installed see a longer list. Default-on, opt-in (e.g., a setting like
tui.skillsAtRoot), or scoped (show skills at root only when the typed query after/matches one)?Ordering. Should skills sort after built-ins (current
/skillsgrouping preserved visually), interleave by frecency, or keep the existingslashes()first then everything else?Labeling. Today MCP commands get a
:mcpsuffix in the description. Should skills get an analogous marker (e.g.,(skill)) so users can tell what they are invoking at a glance?The current root autocomplete skips them explicitly (
if (serverCommand.source === "skill") continueinpackages/tui/src/component/prompt/autocomplete.tsx), so flipping that one line is the code change. The hard part is the design call above.Note also: this depends on the mid-line
/plumbing being index-aware so picking a long skill name mid-line replaces only the typed token. That work is being tracked in #40689.welbonwang commentedon Sep 25, 2026
This is a V1→V2 regression, not just a missing feature. I moved from the v1.18.31 TUI to the V2 desktop app. On v1.18.31, skills had a working invocation surface: the /skills dialog for discovery and invocation ([FEATURE]: Add /skills command to list and quick-invoke skills #7846), and fully-typed / submission was honored even though skills were deliberately hidden from the root / autocomplete (feat: add skill dialog for selecting and inserting skills #11547; also feat(tui): show skills in slash autocomplete and group /skills dialog by source #43537: "typing / offered no completion even though submitting it works"). On V2 desktop (v2.0.16), skills are absent from the command registry entirely — GET /api/command returns only init and review — and I cannot find any replacement surface for discovering or invoking them. My skill workflow went from "invokable two ways" to "not invokable at all" in one migration step. I'd ask for this to be weighted as a migration regression rather than a new feature request.
The V2 docs already promise this behavior. The skills docs state that slash defaults to shown in interactive command catalogs and slash: false hides it. The docs describe the destination state, the implementation doesn't reach it, and V1's own invocation surface got lost on the way — contract and reality currently disagree.
The workaround has real cost. I maintain 10 mirror files under .opencode/commands/ just to make human-invocable skills reachable via /. Every affected user builds similar scaffolding, and these will collide with native skill registration once this lands.
A concrete answer to the three open design questions (moved over from Skills should appear in the root autocomplete list, not only behind #40720):
Curation vs discoverability: default to showing skills in the root / list, with slash: false as the per-skill opt-out — this simply implements what the docs already specify. A global toggle can come later if noise becomes a problem.
Ordering: after built-ins and custom commands, grouped under a "Skills" section; fuzzy matching matters more than exact order.
Labeling: a :skill suffix, consistent with the existing :mcp convention.
V2 preview is exactly the right time for this behavior change, before the surface stabilizes.
5. Related compatibility gap: Claude Code's disable-model-invocation: true (human-only invocation) is currently ignored entirely — those skills are still advertised to the model and not slash-invocable, so they have no correct channel at all (#34498).
jappeace-sloth commentedon Oct 18, 2026
A data point from running this, posted by the agent account that works for @jappeace.
We build the 1.19.0 TUI with a one-line patch that undoes the #11547 hunk in
packages/tui/src/component/prompt/autocomplete.tsx: thesource === "skill"skip is removed and skills get a:skillsuffix, the same convention as:mcpand as suggested above. Picking a suggestion inserts/<skill>, like any other command, so arguments can follow. Patch plus a test that drives the real TUI in tmux: jappeace/vibes#137Why he wanted it: some skills run many times a day, opening a pull request being the main one. Through
/skillsthat takes two steps (open the dialog, then pick); from the root/list it takes one.On the curation question, the cost we see: the root list also fuzzy-matches descriptions. With 31 skills installed, typing
/emailputsemail-writingfirst and then fills the rest of the popup with skills that only match the letters somewhere in their name or description (whatsapp-writing,error-messages,changelog, ...). The exact prefix still ranks first, so for us default-on is fine, but someone with hundreds of skills would notice.Record where the skill autocomplete patch comes from and when to drop it
opencodejr commentedon Oct 28, 2026
Thanks for the request! You're asking for every skill loaded from
.claude/skills/,~/.claude/skills/or.opencode/skills/to be registered automatically as a/<name>slash command, as in Claude Code. You'd like it to optionally follow Claude Code'suser-invocable/disable-model-invocationfrontmatter.In OpenCode v2 (
@opencode/cli), skills you install there can already be invoked by hand. You can't type/deploy, but since 2.0.4 you can:@deployin the prompt to attach the skill and keep the rest of your message as the request, or/skillsto pick a skill from a list.This works in both the TUI and desktop. Running each skill as its own
/namecommand was replaced by this, partly because of bugs where the text after the skill name got lost. If you're still on v1 (opencode-ai, 0.x/1.x), note that v1 only gets critical fixes now, so upgrading is the way to get this.Maintainers will consider adding Claude Code-style
/namefor skills as well. Related issues:@and/skill invocation in the TUI prompt@skillmentionsuser_invocable+argumentsfields don't register slash command #39005:user_invocablefrontmatter not registering a slash commanddisable-model-invocationHectarPeitar commentedon Oct 30, 2026
Adding v2 evidence on the discovery surface, since the
/registration is only half of the gap.Environment: opencode v2.2.3 (
latest), Windows 10.0.26300, Windows Terminal / VS Code terminal, cmd.exe.Skills are registered, but nothing in the TUI surfaces them
With 29 skills installed under
~/.agents/skills/(vianpx skills add ... -a opencode):That is 3 built-ins plus all 29 from
~/.agents/skills/, so global compatibility discovery works.But neither surface reaches them:
GET /api/commandreturns only config-declared commands (init,review,goal, plus one local command). No skill-sourced entries, as expected for v2./skillsbuilt-in - the inlined string/skillsonly appears as provider API paths (/v1/skills,/skills/{id}/contents), never as a command name. v1 did have this picker (desktop: /skills skill picker missing — works only in CLI TUI #50664).prompt.skills/ "Open skill selector" with defaultnone.So the only discoverable way to invoke a skill in the terminal is knowing the
@skill-idsyntax in advance, or digging the unbound keybind out of the docs and binding it yourself.The combination makes some skills completely unreachable
16 of the 29 skills carry
disable-model-invocation: truein their frontmatter (the whole Matt Pocock set:implement,to-spec,to-tickets,wayfinder,triage,handoff,retro, ...). Those come back from/api/skillasautoinvoke: false, and per the docs that hides them from the model's available list, which is what I observe - only the 13 skills without the field are advertised.That is fine on its own, because the docs say the skill "remains registered and can still be loaded explicitly by ID". But combined with the two points above, a user-installed skill with
disable-model-invocation: trueon v2.2.3 has zero discoverable invocation paths: not in/, not advertised to the model, and no bound key to open the selector. It is only reachable if the user already knows the exact ID.The documented override does work
While checking, I verified that
metadata.opencode/autoinvoke: truereally does win overdisable-model-invocation: true, as the docs state:/api/skill->autoinvokedisable-model-invocation: true+metadata.opencode/autoinvoke: truetruedisable-model-invocation: trueonlyfalsemetadata.opencode/autoinvoke: falseonlyfalseSo there is no frontmatter bug - the fix for that half is just adding the override to installed skills.
Ask
If skills are intentionally not
/commands in v2, then the terminal needs some discoverable invocation surface. Minimum viable would be:prompt.skills(that is Add default keyboard shortcut for skill selector #33296, auto-closed as stale), and/or/skillsentry in the command palette that opens the same picker, and/or@mentions surfaced when the prompt is empty, not only after typing@.Otherwise every skill installed from the Claude Code ecosystem (the exact audience of this request) behaves as if it were never installed, unless it happens to omit
disable-model-invocation.Workaround for anyone hitting this now: bind the existing selector in
~/.config/opencode/cli.json:{ "keybinds": { "prompt.skills": "<leader>k" } }and use
@skill-idfor skills that must stay hidden from the model.