Plugin authoring¶
First-party and third-party plugins register components, assets, and optional Explorer
panels through the portable plugin protocol. Study
hedron-sample-kit
alongside this guide.
1. Package layout¶
my_hedron_plugin/
pyproject.toml
src/my_hedron_plugin/
__init__.py
plugin.py
components/Callout/
__init__.py # Callout component + CalloutProps
styles.css
examples.py
2. Entry point¶
In pyproject.toml:
3. Register¶
# plugin.py
from __future__ import annotations
from pathlib import Path
from hedron_core.plugins import PluginCapabilities, PluginContext, PluginMeta
_ROOT = Path(__file__).resolve().parent
_COMPONENT = _ROOT / "components" / "Callout"
PLUGIN_META = PluginMeta(
name="my_plugin",
version="0.1.0", # keep aligned with your distribution version
distribution="my-hedron-plugin",
hedron_version=">=0.20,<0.21",
capabilities=PluginCapabilities(python=True, styles=True, assets=True),
)
def register(ctx: PluginContext) -> None:
ctx.register_component(
logical_id="my-hedron-plugin:callout.Callout",
name="Callout",
module="my_hedron_plugin.components.Callout",
distribution="my-hedron-plugin",
props_model="CalloutProps",
styles_path=str(_COMPONENT / "styles.css"),
folder_path=str(_COMPONENT),
asset_roots=(str(_COMPONENT),),
examples=("default",),
)
register.PLUGIN_META = PLUGIN_META # type: ignore[attr-defined]
4. Version gates¶
PLUGIN_META.versionshould match the published package versionhedron_versionconstrains which Hedron trains load the plugin- Incompatible plugins fail at load with
HED-PLUGIN-0002— do not silently no-op
5. Assets, CSP, and Explorer¶
- Prefer package resources for assets; avoid remote asset URLs unless policy allows
- Do not ship active script / dangerous URL schemes in registered SVG icons
- Optional:
ctx.register_explorer_panel(...)for Explorer UI (see sample kit) - Optional:
ctx.register_diagnostic_owner("HED-MINE-")for plugin-owned codes
6. Test without FastAPI¶
from hedron_core.plugins import PluginContext
from my_hedron_plugin.plugin import PLUGIN_META, register
def test_registers() -> None:
ctx = PluginContext(PLUGIN_META)
register(ctx)
# assert registry contains your logical_id / assets
Load the plugin in CI via the same entry-point path production uses.
7. Publish and version¶
- Pin against
hedron-core(and optionallyhedron) with an upper bound matching the adopter train (for example>=0.20.0,<0.21). - Declare license metadata; do not pull FastAPI/Flask/Django into a core-facing package.
- Ship a CHANGELOG and document Experimental vs Supported claims honestly (What’s ready).
- Prefer extras so absent features add no import or asset cost.
8. Security review checklist¶
- No raw request/session/DB handles crossed into
hedron-coretypes - Assets and HTML use SafeUrl / TrustedHtml where required
- Explorer panels and diagnostics never leak secrets
- Deny-by-default for specialty capabilities (see sample kit / extras specialty surfaces)
- Document failure modes (missing extras, fail-closed policies)
See also¶
- Using plugins (adopter enablement) · Plugins API · Error codes · STABILITY
- Sample kit:
packages/hedron-sample-kit - Layout rules: PROJECT_LAYOUT