Skip to content

feat: make skills invokable as slash commands in the TUI#11390

Merged
thdxr merged 3 commits intodevfrom
feat/skills-slash-commands
Jan 31, 2026
Merged

feat: make skills invokable as slash commands in the TUI#11390
thdxr merged 3 commits intodevfrom
feat/skills-slash-commands

Conversation

@thdxr
Copy link
Contributor

@thdxr thdxr commented Jan 31, 2026

Summary

This PR makes skills invokable as slash commands in the TUI, similar to how custom commands work.

Changes

  • Added Skill.content() method to load skill template content from SKILL.md files
  • Modified Command.list() to include skills as invokable commands
  • Added skill boolean property to Command.Info schema
  • Updated autocomplete to show skills with "(Skill)" label in slash commands
  • Regenerated SDK to include skill property in Command type

How it works

Users can now invoke any skill defined in SKILL.md files by typing /skillname in the TUI. The skill's body content (markdown after the frontmatter) is used as the command template, and arguments are substituted just like with regular commands.

Skills appear in the slash command autocomplete alongside regular commands, marked with "(Skill)" label for clarity.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds the ability to invoke skills as slash commands in the TUI, making skills more accessible through the command interface. Skills defined in SKILL.md files can now be invoked with /skillname syntax, similar to custom commands.

Changes:

  • Added Skill.content() method to extract template content from SKILL.md files
  • Modified Command.list() to include skills as commands with lower priority than existing commands
  • Updated autocomplete UI to display skills with "(Skill)" label for clarity

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
packages/sdk/js/src/v2/gen/types.gen.ts Added optional skill boolean property to Command type in generated SDK
packages/opencode/src/skill/skill.ts Added content() method to load skill markdown content from SKILL.md files
packages/opencode/src/command/index.ts Modified Command.list() to register skills as invokable commands with skill flag and template getter
packages/opencode/src/cli/cmd/tui/component/prompt/autocomplete.tsx Updated command autocomplete to display "(Skill)" label for skill-based commands

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 160 to 161
const md = await ConfigMarkdown.parse(info.location)
return md.content
Copy link

Copilot AI Jan 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The content() method lacks error handling for ConfigMarkdown.parse(), which could throw parsing errors. Unlike the addSkill() function (lines 49-57) which wraps ConfigMarkdown.parse() in a try-catch block and handles ConfigMarkdown.FrontmatterError, this method will propagate any parsing errors up to the caller. When used in Command.list() via the template getter, these errors could cause the entire command listing to fail. Consider adding error handling similar to addSkill(), or at minimum catch and log errors while returning undefined or empty string to maintain graceful degradation.

Suggested change
const md = await ConfigMarkdown.parse(info.location)
return md.content
try {
const md = await ConfigMarkdown.parse(info.location)
return md.content
} catch (error) {
if (error instanceof ConfigMarkdown.FrontmatterError) {
log.error("failed to parse skill markdown frontmatter", {
path: info.location,
error,
})
} else {
log.error("failed to load skill content", {
path: info.location,
error,
})
}
return undefined
}

Copilot uses AI. Check for mistakes.
get template() {
return Skill.content(skill.name).then((content) => content ?? "")
},
hints: [],
Copy link

Copilot AI Jan 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skills are added with an empty hints array, but hints should be computed from the skill template content to support argument placeholders like $1, $2, or $ARGUMENTS. Other command types (default commands at lines 70, 79, config commands at line 93, and MCP prompts at line 119) all compute hints from their templates using the hints() function. Without proper hints, skill templates that use argument placeholders won't provide autocomplete suggestions for those arguments in the TUI. Consider computing hints after loading the skill content, or making hints a getter that computes them lazily from the template.

Copilot uses AI. Check for mistakes.
@thdxr thdxr force-pushed the feat/skills-slash-commands branch from 9059078 to 515b334 Compare January 31, 2026 04:56
@thdxr thdxr force-pushed the feat/skills-slash-commands branch from a7d015f to 2487ddd Compare January 31, 2026 05:41
@thdxr thdxr merged commit 81ac41e into dev Jan 31, 2026
3 checks passed
@thdxr thdxr deleted the feat/skills-slash-commands branch January 31, 2026 05:41
alexyaroshuk pushed a commit to alexyaroshuk/opencode that referenced this pull request Feb 1, 2026
ishaksebsib pushed a commit to ishaksebsib/opencode that referenced this pull request Feb 4, 2026
ishaksebsib pushed a commit to ishaksebsib/opencode that referenced this pull request Feb 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant