diff --git a/mods/sdk/kindred_sdk/__init__.py b/mods/sdk/kindred_sdk/__init__.py index 410e18b31d..7430863ef2 100644 --- a/mods/sdk/kindred_sdk/__init__.py +++ b/mods/sdk/kindred_sdk/__init__.py @@ -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", diff --git a/mods/sdk/kindred_sdk/registry.py b/mods/sdk/kindred_sdk/registry.py new file mode 100644 index 0000000000..6f8f7fc879 --- /dev/null +++ b/mods/sdk/kindred_sdk/registry.py @@ -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()]