Create kindred-addon-sdk package #249

Closed
opened 2026-02-16 17:13:01 +00:00 by forbes · 1 comment
Owner

Summary

Create mods/sdk/ as a Python package providing a stable API for addon integration with Kindred Create's platform features (editing contexts, themes, origins, manifests). This insulates addons from C++ API changes during upstream rebases.

Motivation

ztools and Silo currently call platform APIs directly — Silo uses FreeCADGui.registerEditingOverlay(), and ztools uses Gui.addWorkbenchManipulator() with a custom manipulator class. These are C++ bindings exposed to Python. During an upstream FreeCAD rebase, if signatures change, every addon breaks independently. The SDK provides a single adaptation point.

Package structure

mods/sdk/
├── package.xml
├── Init.py
├── kindred_sdk/
│   ├── __init__.py          # Public API re-exports
│   ├── version.py           # SDK_VERSION, MIN_CREATE_VERSION
│   ├── context.py           # register_context, register_overlay,
│   │                        #   inject_commands, current_context, refresh_context
│   ├── origin.py            # register_origin wrapper
│   ├── theme.py             # get_theme_tokens() → dict of Catppuccin Mocha values
│   ├── manifest.py          # AddonManifest dataclass, package.xml parser
│   ├── dock.py              # Helper for registering dock panels with deferred init
│   └── compat.py            # Version detection, FreeCAD API shimming
└── tests/
    └── test_context.py

Key APIs

Context registration

from kindred_sdk import register_context, register_overlay, inject_commands

register_context(
    context_id="myworkbench.edit",
    match_fn=lambda resolver: ...,
    toolbars=["My Toolbar"],
    priority=50,
)

inject_commands(
    context_id="partdesign.body",
    toolbar="Part Design Helper Features",
    commands=["MyAddon_Tool1", "MyAddon_Tool2"],
)

Theme tokens

from kindred_sdk import get_theme_tokens

tokens = get_theme_tokens()
# {"base": "#1e1e2e", "mantle": "#181825", "blue": "#89b4fa", ...}

Manifest

from kindred_sdk import AddonManifest

manifest = AddonManifest.from_package_xml(Path("mods/ztools/package.xml"))
assert manifest.compatible_with("0.2.0")

Affected files

  • mods/sdk/ — new submodule
  • src/Mod/Create/Init.py — load SDK first, before other addons
  • mods/ztools/InitGui.py — migrate to SDK calls (follow-up issue)
  • mods/silo/freecad/InitGui.py — migrate to SDK calls (follow-up issue)

Acceptance criteria

  • kindred_sdk importable from any addon's Init.py/InitGui.py
  • register_context() wraps FreeCADGui.registerEditingContext() with validation and error handling
  • get_theme_tokens() returns full Catppuccin Mocha palette dict
  • AddonManifest parses existing package.xml files plus <kindred> extensions
  • SDK versioned independently; addons declare sdk_version in their manifest
  • SDK loaded before all other addons by the bootstrap loader

Dependencies

  • Depends on: #1 (manifest-driven loader, so SDK is loaded first)

Notes

The SDK does NOT wrap FreeCAD's modeling API (Part, PartDesign, etc.). Addons use those directly. The SDK only covers Create platform integration: contexts, themes, origins, manifests, and dock panel helpers.

## Summary Create `mods/sdk/` as a Python package providing a stable API for addon integration with Kindred Create's platform features (editing contexts, themes, origins, manifests). This insulates addons from C++ API changes during upstream rebases. ## Motivation ztools and Silo currently call platform APIs directly — Silo uses `FreeCADGui.registerEditingOverlay()`, and ztools uses `Gui.addWorkbenchManipulator()` with a custom manipulator class. These are C++ bindings exposed to Python. During an upstream FreeCAD rebase, if signatures change, every addon breaks independently. The SDK provides a single adaptation point. ## Package structure ``` mods/sdk/ ├── package.xml ├── Init.py ├── kindred_sdk/ │ ├── __init__.py # Public API re-exports │ ├── version.py # SDK_VERSION, MIN_CREATE_VERSION │ ├── context.py # register_context, register_overlay, │ │ # inject_commands, current_context, refresh_context │ ├── origin.py # register_origin wrapper │ ├── theme.py # get_theme_tokens() → dict of Catppuccin Mocha values │ ├── manifest.py # AddonManifest dataclass, package.xml parser │ ├── dock.py # Helper for registering dock panels with deferred init │ └── compat.py # Version detection, FreeCAD API shimming └── tests/ └── test_context.py ``` ## Key APIs ### Context registration ```python from kindred_sdk import register_context, register_overlay, inject_commands register_context( context_id="myworkbench.edit", match_fn=lambda resolver: ..., toolbars=["My Toolbar"], priority=50, ) inject_commands( context_id="partdesign.body", toolbar="Part Design Helper Features", commands=["MyAddon_Tool1", "MyAddon_Tool2"], ) ``` ### Theme tokens ```python from kindred_sdk import get_theme_tokens tokens = get_theme_tokens() # {"base": "#1e1e2e", "mantle": "#181825", "blue": "#89b4fa", ...} ``` ### Manifest ```python from kindred_sdk import AddonManifest manifest = AddonManifest.from_package_xml(Path("mods/ztools/package.xml")) assert manifest.compatible_with("0.2.0") ``` ## Affected files - `mods/sdk/` — new submodule - `src/Mod/Create/Init.py` — load SDK first, before other addons - `mods/ztools/InitGui.py` — migrate to SDK calls (follow-up issue) - `mods/silo/freecad/InitGui.py` — migrate to SDK calls (follow-up issue) ## Acceptance criteria - [ ] `kindred_sdk` importable from any addon's `Init.py`/`InitGui.py` - [ ] `register_context()` wraps `FreeCADGui.registerEditingContext()` with validation and error handling - [ ] `get_theme_tokens()` returns full Catppuccin Mocha palette dict - [ ] `AddonManifest` parses existing `package.xml` files plus `<kindred>` extensions - [ ] SDK versioned independently; addons declare `sdk_version` in their manifest - [ ] SDK loaded before all other addons by the bootstrap loader ## Dependencies - **Depends on:** #1 (manifest-driven loader, so SDK is loaded first) ## Notes The SDK does NOT wrap FreeCAD's modeling API (`Part`, `PartDesign`, etc.). Addons use those directly. The SDK only covers Create platform integration: contexts, themes, origins, manifests, and dock panel helpers.
forbes added the enhancement label 2026-02-16 17:13:01 +00:00
Author
Owner

Scope change: standalone theme module with YAML-driven config. After reviewing the codebase, Catppuccin Mocha colors are duplicated across 5+ locations (icons.py, theme.py, silo_start.py, KindredCreate.cfg, KindredCreate.qss). Updated plan: the SDK theme module becomes a standalone theme system driven by a YAML palette file instead of hardcoded Python dicts. The YAML defines color tokens and the SDK processes them into Python dicts, QSS templates, SVG color injection, and preference pack values. Remaining SDK modules (context, origin, dock, compat) unchanged from original spec.

Scope change: standalone theme module with YAML-driven config. After reviewing the codebase, Catppuccin Mocha colors are duplicated across 5+ locations (icons.py, theme.py, silo_start.py, KindredCreate.cfg, KindredCreate.qss). Updated plan: the SDK theme module becomes a standalone theme system driven by a YAML palette file instead of hardcoded Python dicts. The YAML defines color tokens and the SDK processes them into Python dicts, QSS templates, SVG color injection, and preference pack values. Remaining SDK modules (context, origin, dock, compat) unchanged from original spec.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: kindred/create#249