-
Notifications
You must be signed in to change notification settings - Fork 101
Plugin Marketplace Compatibility: Align with Claude Code & AgentSpec #1457
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
This commit adds the ability to load skills from installed OpenHands skill packages, enabling reusable skill distribution across projects. Features: - Package discovery using Python entry points - Configuration via .openhands/packages.yaml - Functions to list, load, and inspect skill packages - Integration with existing skill loading infrastructure - Comprehensive tests and documentation - Example demonstrating all features New files: - openhands-sdk/openhands/sdk/context/skills/package_loader.py - tests/sdk/context/skill/test_package_loader.py - examples/01_standalone_sdk/04_use_skill_packages.py - docs/skill-packages.md - .openhands/packages.yaml (template) Related to: https://github.com/OpenHands/package-poc
Update the OpenHands SDK package loader to support both manifest.json (Claude Desktop Extensions-aligned) and skill-package.yaml (legacy) formats. Key Changes: - Add _load_descriptor() helper that tries JSON first, falls back to YAML - Update list_skill_packages() to use new descriptor loader - Update get_skill_package() to use new descriptor loader - Update load_skills_from_package() to handle both descriptor formats - Add comprehensive documentation on Claude Code alignment Features: - Full backwards compatibility with existing YAML packages - Cross-platform package support (OpenHands + Claude Desktop) - Automatic format detection and handling - No changes required to existing code using package_loader Documentation: - New claude-code-alignment.md guide - Usage examples for both formats - Migration strategies for existing packages - Integration guidelines This change aligns with OpenHands/package-poc PR #17 which implements the manifest.json format in the ohp package management tool. Related to OpenHands/package-poc#16 Co-authored-by: openhands <openhands@all-hands.dev>
- Removed YAML fallback logic from _load_descriptor() - Updated docstrings to reflect JSON-only support - Simplified load_skills_from_package() to handle only flat JSON structure - Removed dual-format handling code This is a clean break for Scenario 1 - packages must use manifest.json. Co-authored-by: openhands <openhands@all-hands.dev>
- Removed backwards compatibility mentions - Updated usage examples to show flat JSON structure - Clarified manifest.json is required for Scenario 1 - Updated migration section - Simplified benefits section Co-authored-by: openhands <openhands@all-hands.dev>
- Convert test fixtures from YAML to JSON format - Update descriptor access to use flat structure (no metadata/spec nesting) - Fix mock setup for manifest.json instead of skill-package.yaml - Keep yaml import for packages.yaml configuration support - Fix line length issues for ruff compliance - All 13 tests passing Co-authored-by: openhands <openhands@all-hands.dev>
…ll_packages.py - Updated example code to access flat manifest.json structure instead of nested metadata/spec - Fixed descriptor access patterns: descriptor['displayName'] instead of descriptor['metadata']['displayName'] - Renamed from 04_use_skill_packages.py to 31_use_skill_packages.py to match PR #1378 - Updated documentation reference to point to new filename - Added defensive handling for author and repository fields that can be string or object Co-authored-by: openhands <openhands@all-hands.dev>
Add isinstance check before passing triggers to KeywordTrigger to handle untyped frontmatter metadata. This ensures type safety and prevents passing non-list objects. Co-authored-by: openhands <openhands@all-hands.dev>
Automated formatting by yamlfmt to add standard YAML document delimiter. Co-authored-by: openhands <openhands@all-hands.dev>
Coverage Report •
|
||||||||||||||||||||
|
Looks like there are a few issues preventing this PR from being merged!
If you'd like me to help, just leave a comment, like Feel free to include any additional details that might help me get this PR into a better state. You can manage your notification settings |
|
[Automatic Post]: It has been a while since there was any activity on this PR. @jpshackelford, are you still working on it? If so, please go ahead, if not then please request review, close it, or request that someone else follow up. |
Description
This PR builds on the proof-of-concept from #1399 to achieve full compatibility with Claude Code Plugins and AgentSpec standards. The key insight is that marketplace monorepos and Python packages can share the same plugin structure, enabling plugins to be distributed both ways without modification.
implementation in-progress: this PR description guides on-going work on the branch
Vision: Unified Plugin Structure
The Dual-Distribution Model
A plugin repository can serve as both:
The
.plugin/directory structure remains identical in both cases, with Python packaging (pyproject.toml, setup.py) as an optional layer for formal distribution.Example Marketplace Monorepo Structure
Key Principle: The
.plugin/structure is the same whether used bare or packaged.Changes Required for Full Compatibility
1. File Naming & Structure ❌ NOT YET IMPLEMENTED
Current State (PR #1399):
manifest.jsonin package root.plugin/or.claude-plugin/directory structureRequired Changes:
manifest.json→plugin.json.plugin/plugin.json(vendor-neutral, per Plugin 1.0 Definition #1440).claude-plugin/plugin.jsonfor backward compatibilitypackage_loader.pyto check both locations.plugin/>.claude-plugin/Files to Modify:
openhands-sdk/openhands/sdk/context/skills/package_loader.py- Update_load_descriptor()tests/sdk/context/skill/test_package_loader.py- Update all test fixturesdocs/claude-code-alignment.md- Correct documentation2. Schema Alignment ❌ NOT YET IMPLEMENTED
Current State:
{ "name": "simple-code-review", "version": "1.0.0", "skills": [...] }Claude Code plugin.json Schema:
{ "name": "plugin-name", "version": "1.0.0", "displayName": "Human Readable Name", "description": "Plugin description", "author": { "name": "Author Name", "email": "author@example.com" }, "keywords": ["tag1", "tag2"], "license": "MIT", "commands": ["./commands/"], "agents": ["./agents/agent.md"], "hooks": {...}, "mcpServers": {...} }Required Changes:
Note: Current implementation has
skillsarray in manifest.json, but Claude Code uses directory-based discovery with optional overrides in plugin.json.3. AgentSpec SKILL.md Compatibility ❌ NOT YET IMPLEMENTED
Current State (from package_loader.py lines 183-199):
frontmatterlibrarytriggersfield in metadataAgentSpec SKILL.md Requirements (from #1452):
Required Frontmatter Fields:
name- Skill identifier (kebab-case)description- 1-1024 charactersOptional Frontmatter Fields:
license- SPDX identifiercompatibility- Compatibility notesmetadata- Key-value map (author, version, etc.)allowed-tools- Tool restrictions (experimental)OpenHands Extensions (Not in AgentSpec):
triggers- Keyword list for activationinputs- For task skills with variable substitutionmcp_tools- MCP server configurationRequired Changes:
Files to Modify:
openhands-sdk/openhands/sdk/context/skills/skill.py- Add AgentSpec validationopenhands-sdk/openhands/sdk/context/skills/package_loader.py- Use Skill.load_agentspec() method4. Progressive Disclosure Support ❌ NOT YET IMPLEMENTED
AgentSpec Three-Tier Model:
OpenHands Current Model:
Required Changes:
Note: This is a Phase 2 enhancement, not required for initial compatibility.
5. Directory Structure Support⚠️ PARTIAL
Current State:
AgentSpec Structure:
Required Changes:
Files to Consider:
6. Marketplace Integration ❌ NOT YET IMPLEMENTED
Goal: Enable the same
.plugin/structure to work in:Required Changes:
New Functionality Needed:
Testing Current State
What Works (PR #1399):
✅ Entry point discovery via
openhands.skill_packages✅ JSON descriptor loading
✅ Skill file content loading from packages
✅ Frontmatter parsing with triggers
✅ KeywordTrigger creation
✅ Basic package loading tests
What Doesn't Work:
❌
.plugin/directory structure❌
plugin.jsonnaming (usesmanifest.json)❌ AgentSpec SKILL.md validation
❌ Resource directory support (scripts/, references/, assets/)
❌ Progressive disclosure
❌ Filesystem-based marketplace loading
❌ Full schema compatibility with Claude Code
Implementation Priority
Phase 1: Core Compatibility (This PR)
Phase 2: Advanced Features (Future PRs)
Related Issues
.plugin/directory structure)Questions to Resolve
Success Criteria
.plugin/plugin.json(not manifest.json).claude-plugin/plugin.jsonfor compatibilityMigration Path from PR #1399
For existing packages using manifest.json:
manifest.json→plugin.jsonpackage_root/plugin.json→package_root/.plugin/plugin.jsonnameanddescriptionNext Steps
Agent Server images for this PR
• GHCR package: https://github.com/OpenHands/agent-sdk/pkgs/container/agent-server
Variants & Base Images
eclipse-temurin:17-jdknikolaik/python-nodejs:python3.12-nodejs22golang:1.21-bookwormPull (multi-arch manifest)
# Each variant is a multi-arch manifest supporting both amd64 and arm64 docker pull ghcr.io/openhands/agent-server:98b2e5e-pythonRun
All tags pushed for this build
About Multi-Architecture Support
98b2e5e-python) is a multi-arch manifest supporting both amd64 and arm6498b2e5e-python-amd64) are also available if needed