Skip to content

[FEATURE]: Allow plugins to register slash commands #10262

Closed

Description

@nsoufian

Feature hasn't been suggested before.

  • I have verified this feature I'm about to request hasn't been suggested before.

Describe the enhancement you want to request

Problem

Plugin authors currently have no mechanism to interact with users through the OpenCode interface.

Limitations

  • Plugins cannot register dynamic slash commands that appear in the command list
  • Plugins cannot trigger plugin-managed processes from user input
  • Plugins cannot update internal state through UI interactions

Impact

This limits what plugins can offer. Common use cases like toggling plugin modes, triggering syncs, or managing plugin configuration require workarounds outside the OpenCode interface.

Expected behavior

Plugins should be able to define slash commands that users can invoke directly, with the output persisted as session messages.

Activity

  1. added
    discussionUsed for feature requests, proposals, ideas, etc. Open discussion
    on Jan 23, 2026
  2. github-actions commented on Jan 23, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

    These issues explore similar concepts of extending plugin capabilities for user interaction. Feel free to ignore if your specific use case differs from these.

  3. changed the title [-][FEATURE]: Allow plugins to register slash commands for user interaction[/-] [+][FEATURE]: Allow plugins to register slash commands[/+] on Jan 23, 2026
  4. pablontiv commented on Jan 29, 2026

    @pablontiv

    Use Case: Claude Code Compatibility Plugin

    I'm building a plugin (claude-compat) that reads .claude/skills/ and exposes user-invocable skills as slash commands in OpenCode, without file duplication.

    Current Workaround Limitation

    Today, I can expose skills as tools via the tool hook, but this requires agent mediation. The user must say "use the investigar skill" instead of typing /investigar directly.

    What I Need

    The proposed command hook would allow:

    export const ClaudeCompatPlugin: Plugin = async ({ worktree }) => {
      const skills = await discoverClaudeSkills(path.join(worktree, ".claude/skills"))
      
      const commands: Record<string, CommandDef> = {}
      for (const skill of skills.filter(s => s.userInvocable !== false)) {
        commands[skill.name] = {
          template: skill.content,
          description: skill.description,
          hints: skill.argumentHint ? ["$ARGUMENTS"] : [],
        }
      }
      
      return { command: commands }
    }

    Benefits

    • Zero file duplication (reads directly from .claude/)
    • Users migrating from Claude Code get the same /skill-name UX
    • Plugin can handle $ARGUMENTS substitution matching Claude Code behavior

    Happy to help implement this if the design is approved.

  5. grota commented on Feb 4, 2026

    @grota
    Contributor

    Wouldn't an approach like this one fit the need?
    Admittedly, since it seems too easy, I might have misunderstood the scope of the request.

  6. github-actions commented on Apr 6, 2026

    @github-actions
    Contributor

    To stay organized issues are automatically closed after 90 days of no activity. If the issue is still relevant please open a new one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

discussionUsed for feature requests, proposals, ideas, etc. Open discussion

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions