# Kindred Create Repository State Report **Generated:** 2026-01-31 **Branch:** main **Parent repo:** create-0070 @ `364a7057ef` **Submodules:** - ztools @ `8d1f195` (ztools-0065, main) - silo @ `c778825` (silo-0062, main) --- ## Recent Changes (This Session) ### Assembly Solver Fix - `610fd43` — PartDesign datum planes (including ZTools datums) now work correctly as joint references in Assembly. `findPlacement()` in `src/Mod/Assembly/UtilsAssembly.py` extracts geometry from `PartDesign::Plane` and `PartDesign::Point` objects instead of returning zero placements. ### ZTools Bug Fixes - `665bdb2` — Three fixes in the ztools submodule: - Removed `int()` wrapper from `getStandardButtons()` (Qt6/PySide6 compatibility — `StandardButton` enum is not int-castable). - Guarded `_setup_ztools_viewprovider()` against C++ ViewProviders that lack a `Proxy` attribute (`PartDesign::Plane` uses `ViewProviderDatumPlane`, pure C++). - Changed `setEditorMode(prop, 2)` to `setPropertyStatus(prop, "Hidden")` for persistent attachment property hiding across save/reload. ### ZTools Parametric Datums via AttachExtension - `2c716b4` — ZTools datum planes now leverage FreeCAD's built-in `Part::AttachExtension` for automatic parametric updates. Instead of `MapMode = "Deactivated"` with manual placement, each datum type maps to a vanilla `MapMode` (`FlatFace`, `ThreePointsPlane`, `NormalToEdge`, etc.) with appropriate `AttachmentSupport` and `AttachmentOffset`. Datums update automatically when source geometry changes on recompute. ### Stylesheet Fixes (Uncommitted — Staged) - **Tree branch indicators**: Created `branch_closed.svg` and `branch_open.svg` in `images_dark-light/` with Catppuccin `#cdd6f4` chevrons. Added `QTreeView::branch` image rules for expand/collapse states. - **Spinbox/combobox arrows**: Synced all three QSS copies so the CSS border-triangle arrow fix (previously only in `resources/preferences/`) now applies at runtime via `src/Gui/Stylesheets/KindredCreate.qss`. - **Header clipping**: Added `min-height: 20px` to `QHeaderView::section`. - **QSS sync**: All four copies (`resources/preferences/`, `src/Gui/Stylesheets/`, `src/Gui/PreferencePacks/`, `mods/ztools/CatppuccinMocha/`) are now byte-identical. Merged dock widget padding and spreadsheet cell editor styling improvements that existed only in the Stylesheets copy. ### ZTools-PartDesign Merge (Uncommitted — Staged) - `_ZToolsPartDesignManipulator` in `mods/ztools/ztools/InitGui.py` uses `Gui.addWorkbenchManipulator()` to inject ZTools commands into PartDesign's C++ toolbars: - `ZTools_DatumCreator` + `ZTools_DatumManager` → "Part Design Helper Features" - `ZTools_EnhancedPocket` → "Part Design Modeling Features" - `ZTools_RotatedLinearPattern` → "Part Design Transformation Features" - Same commands also inserted into the Part Design menu after `PartDesign_Boolean`. ### Silo Enhancements (Uncommitted — Staged) - **File menu integration**: `SiloMenuManipulator` in `src/Mod/Create/InitGui.py` injects `Silo_New`, `Silo_Open`, `Silo_Save`, `Silo_Commit`, `Silo_Pull`, `Silo_Push`, and `Silo_BOM` into the File menu across all workbenches. - **Toolbar toggle**: `Silo_ToggleMode` checkable command swaps `Ctrl+O/S/N` between standard FreeCAD file commands and Silo equivalents. Appended to the global File toolbar via the manipulator. - **SSL certificate browsing**: Settings dialog now includes a file browser for custom CA certificates (`SslCertPath` preference). `_get_ssl_context()` loads the custom cert before system CAs. - **BOM integration**: Upstream BOM feature (`Silo_BOM` command with tabbed dialog — BOM + Where Used) merged with local changes and added to the Create File menu manipulator. --- ## Architecture Overview ``` create-0070/ Kindred Create (FreeCAD 1.0+ fork) ├── src/ │ ├── Mod/ │ │ ├── Assembly/ Assembly solver (OndselSolver) │ │ ├── PartDesign/ Part modeling (C++ workbench) │ │ ├── Sketcher/ 2D constraint sketcher │ │ ├── Create/ Kindred bootstrap module (Python) │ │ │ └── InitGui.py Loads ztools+silo, installs manipulators │ │ └── ... Other FreeCAD modules │ └── Gui/ │ ├── Stylesheets/ QSS themes + arrow/branch SVGs │ ├── PreferencePacks/ Preference pack bundles │ └── WorkbenchManipulatorPython.cpp Menu/toolbar injection API ├── mods/ │ ├── ztools/ [submodule] ztools-0065 │ │ └── ztools/ │ │ ├── InitGui.py ZToolsWorkbench + PartDesign manipulator │ │ └── ztools/ │ │ ├── commands/ Datum, pattern, pocket, assembly, spreadsheet │ │ ├── datums/core.py Datum creation with AttachExtension │ │ └── resources/ Icons, theme utilities │ └── silo/ [submodule] silo-0062 │ └── pkg/freecad/ │ ├── InitGui.py SiloWorkbench │ └── silo_commands.py 12 commands + SiloClient API └── resources/ └── preferences/KindredCreate/ Canonical QSS + preference pack ``` ### Integration Flow ``` FreeCAD startup └─ src/Mod/Create/InitGui.py exec() ├─ exec(mods/ztools/ztools/InitGui.py) │ ├─ registers ZToolsWorkbench │ └─ installs _ZToolsPartDesignManipulator (global) ├─ exec(mods/silo/pkg/freecad/InitGui.py) │ └─ registers SiloWorkbench └─ QTimer.singleShot(2000): ├─ _setup_silo_menu() │ └─ installs SiloMenuManipulator (global) │ ├─ modifyMenuBar: Silo commands in File menu │ └─ modifyToolBars: Silo_ToggleMode in File toolbar ├─ _check_silo_first_start() └─ _setup_silo_activity_panel() ``` --- ## Submodule Status ### ztools (ztools-0065) | Commit | Description | |--------|-------------| | `8d1f195` | Add PartDesign WorkbenchManipulator and sync Catppuccin theme | | `005348b` | Leverage FreeCAD AttachExtension for parametric datum updates | | `0e95d1c` | Fix Qt6 StandardButton TypeError and C++ ViewProvider Proxy errors | | `98bd444` | Fix workbench init and spreadsheet syntax errors | **Custom commands**: 9 registered - `ZTools_DatumCreator`, `ZTools_DatumManager` - `ZTools_RotatedLinearPattern` - `ZTools_EnhancedPocket` - `ZTools_AssemblyLinearPattern`, `ZTools_AssemblyPolarPattern` - `ZTools_SpreadsheetStyle{Bold,Italic,Underline}`, `ZTools_SpreadsheetAlign{Left,Center,Right}`, `ZTools_Spreadsheet{BgColor,TextColor,QuickAlias}` **Datum types supported**: offset_from_face, offset_from_plane, midplane, 3_points, normal_to_edge, angled, tangent_to_cylinder ### silo (silo-0062) | Commit | Description | |--------|-------------| | `c778825` | Add Silo mode toggle, SSL cert browsing, and BOM menu integration | | `8c06899` | (upstream) Various fixes | | `bce7d5a` | Add BOM handling and routes to API and web UI | | `3a79d89` | feat: add BOM system with API, database repository, and FreeCAD command | | `8e44ed2` | Fix SIGSEGV: defer document open after dialog close | **FreeCAD commands**: 12 registered - `Silo_Open`, `Silo_New`, `Silo_Save`, `Silo_Commit` - `Silo_Pull`, `Silo_Push`, `Silo_Info`, `Silo_BOM` - `Silo_TagProjects`, `Silo_Rollback`, `Silo_SetStatus` - `Silo_Settings`, `Silo_ToggleMode` **API surface**: 38 REST routes covering items, revisions, files, BOM, projects, schemas, and Odoo integration stubs. See `mods/silo/docs/REPOSITORY_STATUS.md` for full route table. **BOM API methods** (new): - `get_bom()`, `get_bom_expanded()`, `get_bom_where_used()` - `add_bom_entry()`, `update_bom_entry()`, `delete_bom_entry()` --- ## Potential Issues ### Critical 1. **Three QSS copies can drift again.** The canonical source is `resources/preferences/KindredCreate/KindredCreate.qss`. The other copies (`src/Gui/Stylesheets/`, `src/Gui/PreferencePacks/`, `mods/ztools/CatppuccinMocha/`) must be kept in sync manually. Consider a build step or symlinks to eliminate duplication. 2. **WorkbenchManipulator command registration timing.** The `_ZToolsPartDesignManipulator` appends commands by name (e.g. `ZTools_DatumCreator`). If the ZTools workbench has not been initialized (first activation) when the user switches to PartDesign, the commands may not be registered yet. The `Create/InitGui.py` `exec()` loads the workbench class but `Initialize()` only runs on first activation. The manipulator API tolerates missing commands silently (toolbar append returns without error), but the buttons won't appear until ZTools initializes. Mitigation: force-activate ZToolsWorkbench during Create module load, or defer manipulator installation. 3. **Silo toggle mode shortcut persistence.** `_swap_shortcuts()` stores original shortcuts in a module-level dict (`_original_shortcuts`). If FreeCAD crashes with Silo mode ON, the original shortcuts are lost and standard commands will have no keyboard shortcuts on next launch. Consider persisting original shortcuts to preferences. ### High 4. **Silo has no authentication.** All API endpoints are publicly accessible. Required before multi-user deployment. See `mods/silo/docs/REPOSITORY_STATUS.md` for full list. 5. **No unit tests for silo FreeCAD commands or ztools.** Python code has zero test coverage. The Go backend also lacks tests per the silo status report. 6. **Assembly solver `findPlacement()` geometry extraction is minimal.** The fix at `UtilsAssembly.py:1006` extracts placement from `obj.Shape.Faces[0]` for `PartDesign::Plane`. This works for planar datums but does not handle edge cases like empty shapes or non-planar datum objects. ### Medium 7. **`Silo_BOM` depends on `get_tracked_object()`** which looks for a `SiloPartNumber` property on document objects. Documents not registered with Silo show a warning dialog. The UX could be improved with a one-click registration flow from the BOM dialog. 8. **`_ZToolsPartDesignManipulator.modifyMenuBar()` inserts after `PartDesign_Boolean`.** If upstream FreeCAD renames or removes this command, the menu insertions silently fail. The toolbar appends (by toolbar name) are more robust. 9. **ZTools `plane_tangent_to_cylinder` falls back to manual placement** because the TangentPlane MapMode requires a vertex reference not currently collected by the UI. This is the only datum type that does not benefit from automatic parametric updates. 10. **Silo `delete_bom_entry()` uses raw `urllib.request`** instead of the `_request()` helper method on `SiloClient`. This bypasses error normalization. Should be refactored to use `self._request("DELETE", ...)`. --- ## Feature Stubs and TODOs ### From silo REPOSITORY_STATUS | Feature | Status | Location | |---------|--------|----------| | Odoo ERP integration | Stub (returns "not yet implemented") | `internal/odoo/` | | Part number date segments | Broken (`formatDate()` returns error) | `internal/partnum/generator.go:102` | | Location/Inventory APIs | Tables exist, no handlers | `migrations/001_initial.sql` | | File locking | Not implemented | — | | Authentication/Authorization | Not implemented | — | | CSRF protection | Not implemented | Web UI only | | CSV import transaction rollback | Not implemented | `bom_handlers.go` | ### From ztools | Feature | Status | Location | |---------|--------|----------| | Tangent-to-cylinder attachment | Manual fallback (no vertex ref) | `datums/core.py` | | Angled datum live editing | AttachmentOffset rotation not updated in panel | `datum_viewprovider.py` | | Assembly pattern undo support | Not implemented | `assembly_pattern_commands.py` | ### From Create integration plan | Phase | Feature | Status | |-------|---------|--------| | 1 | Addon auto-loading | Done (`src/Mod/Create/InitGui.py`) | | 2 | Enhanced Pocket as C++ feature | Not started | | 3 | Datum C++ helpers | Not started (Python AttachExtension approach used instead) | | 4 | Theme system refinement | Partially done (QSS synced, not moved to Create module) | | 5 | Silo deep integration | Done (manipulator-based menu/toolbar injection) | | 6 | Build system integration | Not started | --- ## File Change Summary (Uncommitted) ### Parent repo (create-0070) | File | Change | |------|--------| | `resources/preferences/KindredCreate/KindredCreate.qss` | Branch indicators, header min-height, dock/actiongroup improvements, spreadsheet cell editor | | `src/Gui/Stylesheets/KindredCreate.qss` | Synced with canonical | | `src/Gui/PreferencePacks/KindredCreate/KindredCreate.qss` | Synced with canonical | | `src/Gui/Stylesheets/images_dark-light/branch_closed.svg` | New: right-pointing chevron | | `src/Gui/Stylesheets/images_dark-light/branch_open.svg` | New: down-pointing chevron | | `src/Mod/Create/InitGui.py` | Expanded SiloMenuManipulator (BOM, full commands, toolbar toggle) | | `mods/silo` | Submodule pointer updated | | `mods/ztools` | Submodule pointer updated | ### ztools submodule (committed + pushed) | File | Change | |------|--------| | `ztools/InitGui.py` | Added `_ZToolsPartDesignManipulator` | | `CatppuccinMocha/CatppuccinMocha.qss` | Synced with canonical KindredCreate.qss | ### silo submodule (committed + pushed) | File | Change | |------|--------| | `pkg/freecad/silo_commands.py` | SSL cert browsing, `Silo_ToggleMode`, BOM merge | | `pkg/freecad/InitGui.py` | Added `Silo_ToggleMode` to toolbar | --- ## Silo Integration Path Based on `mods/silo/docs/REPOSITORY_STATUS.md` and the existing `docs/INTEGRATION_PLAN.md`, the integration path forward is: ### Completed - Addon auto-loading via `src/Mod/Create/InitGui.py` - Global File menu injection via `WorkbenchManipulator` - Toolbar toggle for Silo mode (shortcut swapping) - SSL certificate configuration for internal CAs - BOM command integrated into File menu ### Next Steps 1. **Authentication** — LDAP/FreeIPA integration for multi-user. Silo server needs auth middleware; FreeCAD client needs credential storage in preferences. 2. **BOM-Assembly bridge** — Auto-populate Silo BOM from FreeCAD Assembly component links. When a user saves an assembly, extract child part numbers from `Assembly_InsertLink` objects and sync to Silo BOM. 3. **File locking** — Pessimistic locks on checkout (`Silo_Open`) to prevent concurrent edits. Requires server-side lock table and client-side lock-status display. 4. **Status bar integration** — Show current Silo item part number, revision, and sync status in FreeCAD's status bar. Use `FreeCADGui.getMainWindow().statusBar()`. 5. **Build system** — CMake install rules for `mods/` submodules so `.deb` packages include ztools and silo without manual intervention.