# CLAUDE.md — Developer Context for Kindred Create ## Project Overview Kindred Create is a fork of FreeCAD 1.0+ that adds integrated tooling for professional engineering workflows. It ships a context-aware UI system, five addon modules (SDK, Gears, Datums, Silo, Solver), a KCSDK C++ extension layer, a Catppuccin Mocha dark theme, and a pluggable file origin layer on top of FreeCAD's parametric modeling core. - **Kindred Create version:** 0.1.5 - **FreeCAD base version:** 1.2.0 - **License:** LGPL-2.1-or-later - **Repository:** `git.kindred-systems.com/kindred/create` (Gitea) - **Main branch:** `main` ## Quick Start ```bash git clone --recursive ssh://git@git.kindred-systems.com:2222/kindred/create.git cd create pixi run configure # CMake configure (debug by default) pixi run build # Build pixi run install # Install to build dir pixi run freecad # Launch pixi run test # Run C++ tests (ctest) pixi run test-kindred # Run Python/Kindred tests ``` Build variants: append `-debug` or `-release` (e.g., `pixi run build-release`). See `CMakePresets.json` for platform-specific presets (Linux x86_64/aarch64, macOS Intel/ARM, Windows x64). ## Repository Structure ``` create/ ├── src/ │ ├── App/ Core application (C++) │ ├── Base/ Base classes, type system, persistence (C++) │ ├── Gui/ GUI framework (C++) │ │ ├── SDK/ KCSDK C++ library (Kindred feature) │ │ │ ├── bindings/ pybind11 module (kcsdk.so) │ │ │ ├── IPanelProvider.h Dock panel interface │ │ │ ├── IToolbarProvider.h Toolbar interface │ │ │ ├── IMenuProvider.h Menu interface │ │ │ ├── SDKRegistry.h Provider registry │ │ │ ├── ThemeEngine.h Runtime theme token access │ │ │ └── WidgetBridge.h Qt widget creation bridge │ │ ├── EditingContext.h Editing context resolver (Kindred feature) │ │ ├── BreadcrumbToolBar.h Breadcrumb navigation widget (Kindred feature) │ │ ├── FileOrigin.h Abstract origin interface (Kindred feature) │ │ ├── OriginManager.h Origin lifecycle management │ │ ├── CommandOrigin.cpp Origin_Commit/Pull/Push/Info/BOM commands │ │ ├── ApplicationPy.h All FreeCADGui.* Python bindings │ │ ├── Application.h App signals (fastsignals) │ │ ├── Stylesheets/ QSS theme files │ │ └── PreferencePacks/ Preference configurations (build-time generated) │ ├── Mod/ FreeCAD modules (PartDesign, Assembly, Sketcher, etc.) │ │ └── Create/ Kindred Create module │ │ ├── App/ C++ app-side module (AppCreate) │ │ ├── Gui/ C++ GUI-side module (AppCreateGui) │ │ ├── Init.py Console bootstrap — loads addons │ │ ├── InitGui.py GUI bootstrap — loads addons, kc_format, update checker │ │ ├── addon_loader.py Manifest-driven loader with dependency resolution │ │ ├── kc_format.py .kc file format preservation │ │ ├── silo_document.py .kc tree building observer │ │ ├── silo_tree.py Silo metadata tree builder │ │ ├── silo_objects.py Silo tree FeaturePython objects │ │ ├── silo_viewers.py Silo tree MDI viewers │ │ └── silo_viewproviders.py Silo tree ViewProvider icons │ └── 3rdParty/ Vendored dependencies │ ├── OndselSolver/ [submodule] Assembly constraint solver (forked) │ ├── FastSignals/ Signal/slot library (NOT Boost) │ └── GSL/ [submodule] Microsoft Guidelines Support Library ├── mods/ Kindred addon modules │ ├── sdk/ Addon SDK — stable API contract (priority 0) │ ├── gears/ [submodule] Parametric gear workbench (priority 40) │ ├── datums/ [submodule] Unified datum creator (priority 45) │ ├── silo/ [submodule] PLM workbench (priority 60) │ └── solver/ [submodule] Assembly solver research (priority 10) ├── reference/ Archived addons (not built) │ ├── ztools/ Archived — commands migrated to datums + core │ └── quicknav/ Archived — navigation addon ├── docs/ mdBook documentation + architecture docs ├── tests/ C++ unit tests (GoogleTest) ├── package/ Packaging (debian/, rattler-build/) ├── resources/ Branding, icons, desktop integration ├── cMake/ CMake helper modules ├── .gitea/workflows/ CI/CD pipelines ├── CMakeLists.txt Root build configuration (CMake 3.22.0+) ├── CMakePresets.json Platform build presets └── pixi.toml Pixi environment and build tasks ``` ## Build System - **Primary:** CMake 3.22.0+ with Ninja generator - **Environment:** [Pixi](https://pixi.sh) (conda-forge) manages all dependencies - **Key deps:** Qt 6.8.x, Python 3.11.x, OpenCASCADE 7.8.x, PySide6, Boost, VTK, SMESH - **Presets:** `conda-linux-debug`, `conda-linux-release`, `conda-macos-debug`, `conda-macos-release`, `conda-windows-debug`, `conda-windows-release` - **Tasks summary:** | Task | Description | |------|-------------| | `pixi run configure` | CMake configure (debug) | | `pixi run build` | Build (debug) | | `pixi run install` | Install to build dir | | `pixi run freecad` | Launch FreeCAD | | `pixi run test` | C++ tests via ctest | | `pixi run test-kindred` | Python/Kindred test suite | ## Architecture Patterns ### Signals — Use FastSignals, NOT Boost ```cpp #include // See src/Gui/Application.h:121-155 for signal declarations ``` All signals in `src/Gui/` use `fastsignals::signal`. Never use Boost.Signals2. ### Type Checking Across Modules Avoid header dependencies between `src/Gui/` and `src/Mod/` by using runtime type checks: ```cpp auto type = Base::Type::fromName("Sketcher::SketchObject"); if (obj->isDerivedFrom(type)) { ... } ``` ### Python Bindings All `FreeCADGui.*` functions go in `src/Gui/ApplicationPy.h` and `src/Gui/ApplicationPy.cpp`. Use `METH_VARARGS` only (no `METH_KEYWORDS` in this file). Do not create separate files for new Python bindings. ### KCSDK C++ Layer The `src/Gui/SDK/` directory provides a C++ shared library (`libKCSDK`) with pybind11 bindings (`kcsdk` Python module). This is the stable C++ API for Kindred features: - **`IPanelProvider`** — interface for registering dock panels - **`IToolbarProvider`** — interface for toolbar registration - **`IMenuProvider`** — interface for menu registration - **`SDKRegistry`** — central registry for all providers - **`ThemeEngine`** — runtime access to Catppuccin Mocha theme tokens - **`WidgetBridge`** — Qt widget creation from Python factories Python addons access these through `kindred_sdk.*` wrappers (e.g., `kindred_sdk.register_dock_panel()` routes through `kcsdk.register_panel()` + `kcsdk.create_panel()`). Do not use `kcsdk` directly from addons — always use `kindred_sdk`. ### Toolbar Visibility Use `ToolBarItem::DefaultVisibility::Unavailable` to hide toolbars by default, then `ToolBarManager::setState(ForceAvailable)` to show them contextually. This pattern is proven by the Sketcher module. The `appendToolbar` Python API accepts an optional 3rd argument: `"Visible"`, `"Hidden"`, or `"Unavailable"`. ### Editing Context System The `EditingContextResolver` singleton (`src/Gui/EditingContext.h/.cpp`) drives the context-aware UI. It evaluates registered context definitions in priority order and activates the matching one, setting toolbar visibility and updating the `BreadcrumbToolBar`. Built-in contexts: `sketcher.edit`, `assembly.edit`, `partdesign.feature`, `partdesign.body`, `assembly.idle`, `spreadsheet`, `empty_document`, `no_document`. Python API (prefer `kindred_sdk` wrappers over direct `FreeCADGui` calls): - `kindred_sdk.register_context()` — register a new context - `kindred_sdk.register_overlay()` — conditional toolbar overlay - `kindred_sdk.inject_commands()` — add commands to existing contexts - `kindred_sdk.current_context()` — query active context - `kindred_sdk.refresh_context()` — force re-evaluation ### Addon Loading Addons in `mods/` are loaded by `src/Mod/Create/addon_loader.py`. Each addon provides a `package.xml` at the mod root with `` extensions declaring version bounds, load priority, and dependencies. The loader discovers manifests, validates version bounds, and resolves load order via topological sort on dependencies, breaking ties by `(load_priority, name)`. Current load order: **sdk** (0) → **solver** (10) → **gears** (40) → **datums** (45) → **silo** (60). A `` tag in `package.xml` is required for `InitGui.py` to be loaded, even if no actual workbench is registered. The `` element within `` specifies where `Init.py`/`InitGui.py` live relative to the mod root (e.g., `freecad` for silo, `datums` for datums, `./` for sdk). ### Deferred Initialization GUI setup uses `QTimer.singleShot` with staggered delays. Create core (`src/Mod/Create/InitGui.py`) handles: - 500ms: `.kc` file format registration - 10000ms: Update checker Each addon manages its own deferred setup in its `InitGui.py`. For example, Silo (`mods/silo/InitGui.py`) defers: - 500ms: kindred:// URL handler - 600ms: Document observer for .kc tree building - 2000ms: Auth dock panel (via `kindred_sdk.register_dock_panel`) - 2500ms: Silo overlay context - 3000ms: First-start settings check - 4000ms: Activity dock panel (via `kindred_sdk.register_dock_panel`) ### Unified Origin System File operations (New, Open, Save, Commit, Pull, Push) are abstracted behind `FileOrigin` (`src/Gui/FileOrigin.h`). `LocalFileOrigin` handles local files; `SiloOrigin` (`mods/silo/freecad/silo_origin.py`) backs Silo-tracked documents. The active origin is selected automatically based on document properties (`SiloItemId`, `SiloPartNumber`). Origins are registered via `kindred_sdk.register_origin()`. Query functions (`list_origins`, `active_origin`, `get_origin`, `set_active_origin`) route through the `kcsdk` C++ module. ## Submodules | Path | Repository | Branch | Purpose | |------|------------|--------|---------| | `mods/silo` | `git.kindred-systems.com/kindred/silo-mod` | `main` | PLM workbench (includes silo-client submodule) | | `mods/gears` | `git.kindred-systems.com/kindred/gears` | `main` | Parametric gear generation workbench | | `mods/datums` | `git.kindred-systems.com/kindred/datums` | `main` | Unified datum creator (plane, axis, point) | | `mods/solver` | `git.kindred-systems.com/kindred/solver` | `main` | Assembly solver research (GNN-based) | | `src/3rdParty/OndselSolver` | `git.kindred-systems.com/kindred/solver` | — | Constraint solver (forked with NR fix) | | `src/3rdParty/GSL` | `github.com/microsoft/GSL` | — | Guidelines Support Library | | `src/Mod/AddonManager` | `github.com/FreeCAD/AddonManager` | — | FreeCAD addon manager | | `tests/lib` | `github.com/google/googletest` | — | C++ test framework | Update a submodule: ```bash cd mods/silo git checkout main && git pull cd ../.. git add mods/silo git commit -m "chore: update silo submodule" ``` Initialize all submodules: `git submodule update --init --recursive` ## Key Addon Modules ### SDK (`mods/sdk/`) Stable API contract for addons. Python package `kindred_sdk` wraps the KCSDK C++ module, providing: - **Editing contexts:** `register_context()`, `register_overlay()`, `inject_commands()`, `refresh_context()` - **Origins:** `register_origin()`, `unregister_origin()`, `list_origins()`, `active_origin()` - **Dock panels:** `register_dock_panel(object_name, title, factory, area, delay_ms)` - **Commands:** `register_command(cmd_id, classname, pixmap, tooltip)` - **Theme:** `get_theme_tokens()`, `load_palette()` (Catppuccin Mocha YAML palette) - **Toolbars/Menus:** `register_toolbar()`, `register_menu()` - **Version:** `create_version()`, `freecad_version()` Addons should use `kindred_sdk.*` instead of `FreeCADGui.*` internals where possible. ### Gears (`mods/gears/`) Parametric gear workbench. Provides `GearWorkbench` with gear generation and analysis tools. Code lives in `freecad/gears/` (workbench) and `pygears/` (computational library). Priority 40, depends on SDK. ### Datums (`mods/datums/`) Unified datum creator that replaces the three stock PartDesign datum commands (Plane, Line, Point) with a single `Create_DatumCreator` command. Features: - 16 smart creation modes (7 plane, 4 axis, 5 point) - Auto-detection engine: selects best mode from geometry selection - Mode override combo for manual selection - Dynamic parameter UI (offset, angle, position, XYZ) - Edit panel with real-time parameter updates via AttachExtension - Injected into `partdesign.body` and `partdesign.feature` contexts via SDK Source: `mods/datums/datums/` (command.py, core.py, panel.py, detection.py, edit_panel.py). Priority 45, depends on SDK. ### Silo (`mods/silo/`) PLM workbench with 14 commands for parts lifecycle management. Go REST API server + PostgreSQL + MinIO backend. FreeCAD client communicates via shared `silo-client` submodule. Structure: root-level `package.xml`/`Init.py`/`InitGui.py`, workbench code in `freecad/`, client library in `silo-client/`. All deferred setup (origin, overlay, dock panels, document observer) is self-contained in `mods/silo/InitGui.py`. Silo origin detection: `silo_origin.py:ownsDocument()` checks for `SiloItemId`/`SiloPartNumber` properties on the active document. Origin registered via `kindred_sdk.register_origin()`. ### Solver (`mods/solver/`) Assembly solver research addon (GNN-based). Pure Python, priority 10. Provides `KindredSolverBackend` for experimental assembly constraint solving. ## Theme - **Canonical source:** `src/Gui/Stylesheets/KindredCreate.qss` - The PreferencePacks copy at `src/Gui/PreferencePacks/KindredCreate/KindredCreate.qss` is **generated at build time** via `configure_file()`. Only edit the Stylesheets copy. - Color palette: Catppuccin Mocha (26 colors + 14 semantic roles, defined in `mods/sdk/kindred_sdk/palettes/catppuccin-mocha.yaml`) - Runtime access: `kindred_sdk.get_theme_tokens()` returns palette dict; C++ side via `ThemeEngine` in `src/Gui/SDK/` - Default preferences: `src/Gui/PreferencePacks/KindredCreate/KindredCreate.cfg` ## Git Conventions ### Branch Names `type/kebab-case-description` Types: `feat/`, `fix/`, `chore/`, `docs/`, `refactor/`, `art/` ### Commit Messages [Conventional Commits](https://www.conventionalcommits.org/): ``` type(scope): lowercase imperative description ``` | Prefix | Purpose | |--------|---------| | `feat:` | New feature | | `fix:` | Bug fix | | `chore:` | Maintenance, dependencies | | `docs:` | Documentation only | | `art:` | Icons, theme, visual assets | | `refactor:` | Code restructuring | Scopes: `solver`, `sketcher`, `editing-context`, `toolbar`, `datums`, `silo`, `gears`, `sdk`, `breadcrumb`, `gui`, `assembly`, `ci`, `theme`, or omitted. ### PR Workflow 1. Create a branch from `main`: `git checkout -b feat/my-feature main` 2. Commit with conventional commit messages 3. Push and open a PR against `main` via Gitea (or `tea pulls create`) 4. CI runs automatically on PRs ### Code Style - **C++:** clang-format (`.clang-format`), clang-tidy (`.clang-tidy`) - **Python:** black (100-char line length), pylint (`.pylintrc`) - **Pre-commit hooks:** `pre-commit install` (runs clang-format, black, trailing-whitespace, etc.) ## CI/CD - **Build:** `.gitea/workflows/build.yml` — runs on pushes to `main` and on PRs - **Release:** `.gitea/workflows/release.yml` — triggered by `v*` tags, builds AppImage and .deb - **Platform:** Currently Linux x86_64 only in CI; other platforms have presets but no runners yet ## Documentation | Document | Content | |----------|---------| | `README.md` | Project overview, installation, usage | | `CONTRIBUTING.md` | Branch workflow, commit conventions, code style | | `docs/ARCHITECTURE.md` | Bootstrap flow, addon lifecycle, source layout | | `docs/COMPONENTS.md` | Feature inventory (Silo, origin, theme, icons) | | `docs/KNOWN_ISSUES.md` | Known issues, incomplete features, next steps | | `docs/INTEGRATION_PLAN.md` | 5-layer architecture, phase status | | `docs/CI_CD.md` | Build and release workflows | | `docs/KC_SPECIFICATION.md` | .kc file format specification | | `docs/UPSTREAM.md` | FreeCAD upstream merge strategy | | `docs/INTER_SOLVER.md` | Assembly solver integration | | `docs/BOM_MERGE.md` | BOM-Assembly bridge specification | The `docs/src/` directory contains an mdBook site with detailed guides organized by topic (architecture, development, guide, reference, silo-server, solver). ## Issue Tracker Issues are tracked on Gitea at `git.kindred-systems.com/kindred/create/issues`. Use the `tea` CLI for local interaction: ```bash tea issues # List open issues tea issues 123 # View issue #123 details tea pulls create # Create a PR ``` ## Known Issues and Pitfalls 1. **Silo auth not production-hardened** — LDAP/OIDC backends are coded but need infrastructure deployment 2. **No unit tests** for Silo FreeCAD commands or Go backend 3. **Assembly solver datum handling is minimal** — joints referencing datum planes/points may produce incorrect placement 4. **`Silo_BOM` requires Silo-tracked document** — unregistered documents show a warning with no registration path 5. **QSS edits** — only edit `src/Gui/Stylesheets/KindredCreate.qss`; the PreferencePacks copy is auto-generated 6. **Archived addons** — `reference/ztools/` and `reference/quicknav/` are archived source for reference only; they are not built or loaded