You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -327,5 +329,5 @@ faking, so they're recorded with their blockers, not stubbed.
327
329
-[x]**T7 — `kc_mpn_resolve` (full)** (Todo §4). Now hits the real distributor aggregator (stock/price/lifecycle/datasheet, fails closed per FP#5) + pulls symbol/footprint candidates from a new kiserver `GET /project/{id}/library/search` route over the existing `LibraryIndex`. 5 mpn tests + 3 route tests; existing tests made hermetic. ✅ (candidates are richer once T9's bundled mirror is wired).
328
330
-[x]**T8 — FR-043 drop-to-import** (Todo §8). Drag-drop a `.kicad_sym`/`.kicad_mod` onto the editor → kiserver `POST /project/{id}/library/import` (writes the file into a project-local `imported-libs/` or `<nick>.pretty/`, idempotently registers a `sym-lib-table`/`fp-lib-table` row, strips path traversal) + client `useLibraryImport` hook & `LibraryImportDropZone` (extension-inferred kind, error surfacing). 6 route tests + 5 client tests; client typecheck green. ✅ (also fixed a pre-existing `BomView.tsx` TS6133 by wiring the `lastRequestId` stale-response guard into its async `load`.)
329
331
- [x] **T9 — Bundled `libs/` mirror** (Todo §3). Real pinned mirror under `libs/`: 5 whole `.kicad_sym` libraries (Device, power, Connector, Regulator_Switching, RF_Module) + the exact `.kicad_mod` footprints the examples place, all fetched from KiCad GitLab at tag `9.0.0` and SHA-256-pinned in `MANIFEST.toml` by `scripts/populate_libs.py` (`--pin` re-fetches+repins; default mode verifies + self-heals per D6). `sym-lib-table`/`fp-lib-table` register them via `${KICLAUDE_BUNDLED_LIBS}`; `LICENSE.md` carries the CC-BY-SA-4.0 + KiCad Library Exception attribution. kiserver `GET /project/{id}/library/search` now resolves the project's own libs **and** the bundled mirror (`bundled_libs_dir()` + `_merge_hits`, FR-040). Empirical gate: `Device:R`/`Connector:USB_C_*` resolve through the route from a project with an empty table (9 tests). **Also fixed the examples' fictional/wrong library refs to real KiCad 9.0.0 parts** (per the user's call): blinky `MCU_Espressif:`→`RF_Module:ESP32-S3-WROOM-1`; esp32_c6_rf `ESP32-C6-WROOM-1`→`ESP32-C6-MINI-1`, fabricated `Package_BGA:DDR3L_BGA-16_4x4_P0.8mm`→real `BGA-16_1.92x1.92mm_Layout4x4_P0.5mm` (Value `MT41K256M16-DDR3L`→`BGA-16`, since that real DRAM is FBGA-96), `RF_Connectors:U.FL_Molex_73412-0110`→`Connector_Coaxial:U.FL_Molex_MCRF_73412-0110_Vertical`; buck_subsystem `Regulator_Switching:TPS562201`→pin-identical real `TPS562202` (+ matching datasheet URL). Golden round-trip (M0-Q-02) + snapshot re-verified green. ✅
330
-
-[ ]**T10 — STEP geometry parsing** (Todo §6) — **BLOCKED, not completing.** Real `.step` mesh parsing needs `occt-import-js` (~20 MB wasm); SPEC §11 defers it to M4. The placement scene (`three_scene.rs`) + marker-box viewer already exist. Recorded, not stubbed.
332
+
- [x] **T10 — STEP geometry parsing** (Todo §6 / FR-029 / SPEC §6.6 / D6) — pulled forward from M4. `packages/kithree/src/step.ts` decodes STEP → mesh via `occt-import-js` (OpenCASCADE wasm — the kernel KiCad itself uses, so it handles real trimmed-NURBS B-rep); `loadThreeSceneWithModels` fetches + tessellates each placement's model (caching by `model_path`, one parse shared across instances) and renders real geometry, **falling back to the colour-coded placement box** when a model is missing/undecodable (the common offline case). kiserver `GET /project/{id}/model3d` resolves the footprint `(model …)` ref — env-var prefixes (`KICAD7/8/9_3DMODEL_DIR`, `KICLAUDE_BUNDLED_LIBS`), `.wrl`→`.step` sibling swap, path-traversal-safe — and streams STEP bytes from the bundled mirror. `populate_libs.py` seeds 4 real `.step` models into `libs/packages3D/` (ESP32-S3-WROOM-1, BGA-16, C_0402, C_0603; ESP32-C6-MINI-1 + U.FL ship only `.wrl` upstream → box-fallback). **Empirical gate**: a real KiCad `C_0402.step` tessellates to non-trivial geometry through the decoder, the route serves its bytes, the scene loader renders it (6 kithree + 9 kiserver tests). ✅ Remaining for M4: mounting the async loader in the React `Viewer`/`ThreePage` (gateway `model3d` proxy + vite wasm-asset serving) — pure UI wiring; the parsing/serving is done.
331
333
-[ ]**T11 — Zone-fill `simple` XOR ≤ 0.01** (Todo §7) — **BLOCKED, not completing.**`docs/plans/2026-05-24-m2-r-05d-edge-aligned-offset.md` empirically ruled this out across 6 attempts; needs a multi-week from-scratch KiCad `ClipperOffset` port. Gate held at the documented 0.015 floor. Decision item, not an implementable task.
0 commit comments