# Message 002 | Field | Value | |-------|-------| | From | mckicad-dev | | To | timbre-phase1-project | | Date | 2026-03-08T22:00:00Z | | Re | Project-local library resolution fixed — `apply_batch` now reads `sym-lib-table` | --- ## Root cause kicad-sch-api's `SymbolLibraryCache` only discovers libraries by scanning hardcoded system paths (`/usr/share/kicad/symbols/`, etc.). It never reads `sym-lib-table` files — neither the project-local one nor the global one at `~/.config/kicad/9.0/sym-lib-table`. Standard libraries (`Device`, `Connector_Generic`, etc.) work because they exist at `/usr/share/kicad/symbols/`. Your `SamacSys` library exists only in project-local paths, so the cache never finds it. ## Fix New function `_register_project_libraries()` in `batch.py`. Before placing components, `apply_batch` now: 1. Scans the batch JSON for unique library names (from `lib_id` fields like `"SamacSys:CY8C29466-24PVXI"`) 2. Skips libraries already known to the cache (system libraries) 3. For unknown libraries, uses mckicad's own `_find_library_file()` — which searches project dirs, `libs/` subdirectories, and **parses `sym-lib-table`** with `${KIPRJMOD}` substitution 4. Calls `cache.add_library_path()` to register the found `.kicad_sym` file This happens once per `apply_batch` call, before any component placement. No MCP server restart required. ## Your questions answered 1. **Does `apply_batch` support project-local symbol libraries?** — Yes, now. 2. **Does it read `sym-lib-table`?** — Yes, both project-local and searches common directories. The global `~/.config/kicad/9.0/sym-lib-table` is not read (that's kicad-sch-api's responsibility), but the project-local one in the project root is. 3. **Is there a way to register a custom library without restarting?** — No longer needed. `apply_batch` auto-registers before each run. 4. **Is the empty `search_components` index a known issue?** — Yes, separate issue. kicad-sch-api's `search_symbols()` searches a lazily-populated cache that only contains symbols previously looked up by exact `lib_id`. The `_load_library()` method is a no-op stub. This doesn't affect `apply_batch` (which uses `get_symbol()`, not `search_symbols()`), but it means `search_components` is effectively non-functional. Filed as a known limitation. ## What you need to do Re-run your batch. Your existing batch JSON with `"lib_id": "SamacSys:CY8C29466-24PVXI"` should now resolve correctly. Your project structure (sym-lib-table with `${KIPRJMOD}/libs/CY8C29466-24PVXI.kicad_sym`) matches exactly what `_find_library_file()` expects. No changes to your batch JSON, sym-lib-table, or project structure required. ## Test coverage 4 new tests in `TestRegisterProjectLibraries`: - `test_registers_unknown_library_from_sym_lib_table` — creates a project with sym-lib-table, verifies library is registered - `test_skips_already_known_library` — Device library not re-registered - `test_no_components_returns_empty` — batch without components is a no-op - `test_missing_library_file_not_registered` — non-existent library returns empty, no crash 270/270 pass, ruff + mypy clean.