Skip to content

Conversation

@jpshackelford
Copy link
Contributor

@jpshackelford jpshackelford commented Dec 15, 2025

Description

This PR provides initial proof-of-concept support for distributing OpenHands plugins as Python packages with a manifest.json descriptor. This implementation enables early experimentation with package-based plugin distribution but is expected to be superseded by a more comprehensive implementation that fully aligns with the broader plugin architecture vision outlined in #1440, #1452, and OpenHands#12085.

Plugin Distribution Context

OpenHands supports two complementary forms of plugin distribution, each with distinct advantages:

  1. Bare Git Repository Marketplaces (See [TODO: add PR/issue reference])

    • Easy to setup without formal build processes
    • No SDLC overhead or complex versioning requirements
    • Ideal for simple markdown-only plugins
    • Quick iteration and sharing within teams
  2. Python Package Distribution (This PR - POC: support for Python package-based plugin loading #1399)

    • Formal versioning and release controls
    • Better suited for plugins containing code alongside markdown
    • Integration with existing Python packaging ecosystem (PyPI, etc.)
    • Dependency management and installation tooling

Status & Future Work

Important: This PR implements an initial proof of concept that:

  • Uses manifest.json format aligned with Claude Desktop Extensions
  • Supports basic package loading and skill discovery
  • Provides a foundation for experimentation

Expected to be superseded by: A future PR that implements the full plugin architecture from #1440 and #1452, including:

  • Support for .plugin/ directory structure with plugin.json manifests
  • AgentSkills-compatible SKILL.md format with frontmatter validation
  • Progressive disclosure and resource directory support (scripts/, references/, assets/)
  • Full compatibility with Claude Code Plugins and AgentSpec standards

Key Changes in This PR

  • manifest.json Support: Claude Code-aligned JSON format for skill packages
  • Simplified package_loader.py: Reads manifest.json format (removed YAML support)
  • Updated Tests: All tests use manifest.json format
  • Documentation: Migration guide and usage examples

Type of Change

  • New feature (proof of concept)
  • Documentation update
  • Test updates

manifest.json Format Example

{
  "name": "simple-code-review",
  "version": "1.0.0",
  "displayName": "Simple Code Review",
  "description": "Basic code review skills",
  "author": {
    "name": "OpenHands Team",
    "email": "team@openhands.ai"
  },
  "keywords": ["code-review", "security"],
  "license": "MIT",
  "skills": [
    {
      "name": "code-review",
      "description": "Guidelines for thorough code review",
      "path": "skills/code_review.md",
      "type": "keyword-triggered",
      "triggers": ["codereview", "review-code"]
    }
  ]
}

Testing

✅ All 13 package loader tests passing
✅ Ruff format and lint checks passing

Related

  • Issue #1440 - Plugin 1.0 Definition
  • Issue #1452 - AgentSkills Compatibility
  • Issue OpenHands#12085 - Plugin Packaging & Marketplace Vision
  • Related PR in package-poc: OpenHands/package-poc#17
  • Issue: OpenHands/package-poc#16

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>
@github-actions
Copy link
Contributor

github-actions bot commented Dec 16, 2025

Coverage

Coverage Report •
FileStmtsMissCoverMissing
openhands-sdk/openhands/sdk/context/skills
   package_loader.py11710113%38–39, 60, 62, 64–65, 67, 70, 72, 75, 77, 79, 96, 98–100, 102, 105, 107, 112–114, 116, 142–144, 146–147, 149–150, 154, 156, 158–160, 162–163, 166, 168, 170, 174, 179, 181, 183–185, 188–190, 192–194, 197, 202–203, 205, 207, 209–210, 213, 215, 220, 239–240, 242–250, 252, 270, 272–273, 275–278, 280–281, 283, 285–287, 289–291, 293–295, 297–299, 315, 317–319, 321
TOTAL12991590354% 

jpshackelford and others added 2 commits December 18, 2025 21:51
…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>
@openhands-ai
Copy link

openhands-ai bot commented Dec 19, 2025

Looks like there are a few issues preventing this PR from being merged!

  • GitHub Actions are failing:
    • [Optional] Docs example

If you'd like me to help, just leave a comment, like

@OpenHands please fix the failing actions on PR #1399 at branch `openhands/align-package-loader-with-claude-code`

Feel free to include any additional details that might help me get this PR into a better state.

You can manage your notification settings

jpshackelford added a commit to OpenHands/docs that referenced this pull request Dec 19, 2025
This adds comprehensive documentation for the new skill packages feature,
covering installation, loading, configuration, and package creation.

Related to: OpenHands/software-agent-sdk#1399

Co-authored-by: openhands <openhands@all-hands.dev>
@jpshackelford
Copy link
Contributor Author

📚 Documentation PR Created

The documentation for the skill packages example has been added to the docs repository:

This resolves the failing check requiring documentation for examples/01_standalone_sdk/31_use_skill_packages.py.

The documentation covers:

  • Installing skill packages
  • Discovering and inspecting packages
  • Loading skills (configuration-based and programmatic)
  • Package manifest format
  • Creating custom packages
  • Integration with AgentContext

@jpshackelford
Copy link
Contributor Author

jpshackelford commented Dec 19, 2025

Note that this PR needs additional work to bring into closer alignment with the vision for #1440 and related issues. We will leave this as is since it is currently supporting a working demo and we will carry on the work in #1457, closing this one when we are done.

@jpshackelford jpshackelford changed the title Align package_loader with Claude Code manifest.json format POC: support for Python package-based plugin loading Dec 19, 2025
@all-hands-bot
Copy link
Collaborator

[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.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants