feat(sdk): add addon registry wrappers to kindred_sdk (#384)
All checks were successful
Build and Test / build (pull_request) Successful in 29m35s

New module kindred_sdk/registry.py wraps FreeCAD.KindredAddons so
addons use a stable SDK import instead of reaching into FreeCAD
internals directly.

New public API:
- sdk.is_addon_loaded(name) — boolean check
- sdk.addon_version(name) — version string or None
- sdk.loaded_addons() — list of loaded addon names in load order
This commit is contained in:
forbes
2026-03-04 09:36:17 -06:00
parent d84049b905
commit 8c5d259e79
2 changed files with 57 additions and 0 deletions

View File

@@ -21,6 +21,7 @@ from kindred_sdk.origin import (
set_active_origin,
unregister_origin,
)
from kindred_sdk.registry import addon_version, is_addon_loaded, loaded_addons
from kindred_sdk.statusbar import register_status_widget
from kindred_sdk.theme import get_theme_tokens, load_palette
from kindred_sdk.toolbar import register_toolbar
@@ -29,14 +30,17 @@ from kindred_sdk.version import SDK_VERSION
__all__ = [
"SDK_VERSION",
"active_origin",
"addon_version",
"create_version",
"current_context",
"freecad_version",
"get_origin",
"get_theme_tokens",
"inject_commands",
"is_addon_loaded",
"list_origins",
"load_palette",
"loaded_addons",
"refresh_context",
"register_command",
"register_context",

View File

@@ -0,0 +1,53 @@
# kindred_sdk.registry — addon registry queries
#
# Thin wrappers around FreeCAD.KindredAddons (AddonRegistry) so addons
# use a stable SDK import instead of reaching into FreeCAD internals.
import FreeCAD
def _get_registry():
"""Return the AddonRegistry singleton, or None if not yet initialized."""
return getattr(FreeCAD, "KindredAddons", None)
def is_addon_loaded(name: str) -> bool:
"""Check whether an addon loaded successfully.
>>> import kindred_sdk as sdk
>>> sdk.is_addon_loaded("gears")
True
"""
registry = _get_registry()
if registry is None:
return False
return registry.is_loaded(name)
def addon_version(name: str):
"""Return the version string for an addon, or None if not found.
>>> import kindred_sdk as sdk
>>> sdk.addon_version("gears")
'0.1.0'
"""
registry = _get_registry()
if registry is None:
return None
manifest = registry.get(name)
if manifest is None:
return None
return manifest.version
def loaded_addons() -> list[str]:
"""Return the names of all successfully loaded addons, in load order.
>>> import kindred_sdk as sdk
>>> sdk.loaded_addons()
['sdk', 'solver', 'gears', 'datums', 'silo']
"""
registry = _get_registry()
if registry is None:
return []
return [m.name for m in registry.loaded()]