Skip to content

Plugin commands should be loaded as keyword-triggered skills #1674

@jpshackelford

Description

@jpshackelford

Problem

When loading plugins via Plugin.load(), markdown files in the commands/ directory are loaded into plugin.commands but are not merged into the agent context as skills. Only files in the skills/ directory become part of the agent's context.

This means Claude Code format plugins that use commands/ (which is the standard location for slash commands) don't work correctly with OpenHands - the agent never receives the command instructions.

Current Behavior

In plugin.py:

  • _load_skills() loads from skills/ directory
  • _load_commands() loads from commands/ directory

In conversation_service.py (_merge_plugin_into_request):

  • Only plugin.skills is merged into the agent context
  • plugin.commands is ignored

Example

Given a plugin structure:

city-weather/
├── .claude-plugin/
│   └── plugin.json
└── commands/
    └── now.md          # Weather command instructions

The now.md file is loaded but never added to the agent's skills, so the agent doesn't know how to handle weather requests using the plugin's instructions.

Proposed Solution

Treat markdown files in the commands/ directory as keyword-triggered skills using the Claude Code namespacing format:

  1. When loading commands from commands/, convert them to Skill objects
  2. Set the skill's trigger to a KeywordTrigger using the format /<plugin-name>:<command-name>
  3. Merge these command-based skills into the agent context alongside regular skills

Example Trigger Format

For a plugin named city-weather with a command now.md:

  • Trigger keyword: /city-weather:now
  • When user types /city-weather:now Tokyo, the skill activates with $ARGUMENTS = Tokyo

Implementation Notes

  1. In _load_commands() or a new helper, create Skill objects from CommandDefinition
  2. Set trigger = KeywordTrigger(keywords=["/<plugin-name>:<command-name>"])
  3. The skill content should include the command's markdown with $ARGUMENTS placeholder
  4. In _merge_plugin_into_request(), merge both plugin.skills and the converted commands, but don't duplicate loading of the items in the command directory.

Context

References

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions