Running the new --all on the remaining 4 Pro projects (X86 motherboard,
220V power supply, Taishan Pi, Liangshan Pi) surfaced two crash modes
not covered by ESP-VoCat:
1. Odd inner-layer count → KiCad rejects the file at load with
"3 is not a valid layer count". The 220V power boards have one
used inner SIGNAL layer (3 copper total: F.Cu / In1.Cu / B.Cu),
but KiCad requires an even copper count. Fixed pcb_writer to pad
with one empty inner layer when the inner count is odd, so the
total stays even (2, 4, 6, ...).
2. Two BOARDs sharing the same META.title — twin "显示板" boards in
the 220V power project — landed in the same project directory
and the second silently overwrote the first's .kicad_sch /
.kicad_pcb / .kicad_pro. Fixed --all to detect title collisions
and suffix every colliding basename with the BOARD uuid prefix
(so both '显示板' boards become '显示板_52e8cc76' and
'显示板_55d32906' rather than one quietly winning).
71 → 73 unit tests pass (test_odd_inner_signal_count_padded_to_even_total
+ test_duplicate_board_titles_get_distinct_basenames).
Tangentially noted while running this: Taishan Pi and Liangshan Pi are
Pro 2.x JSON, not EPRO2 streams — our replay layer reads the files but
doesn't decode docType, so SCH/PCB grouping returns nothing. Pro 2.x
needs a separate writer; out of scope for this commit.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
KiCad pairs project files purely by basename + same directory: a folder
holding `Foo.kicad_pro`, `Foo.kicad_sch`, `Foo.kicad_pcb` opens as one
project on double-click of the .kicad_pro, with cross-tool navigation
(open footprint from schematic etc) wired up automatically.
- pro_writer.write_kicad_pro() renders the minimal KiCad 8 JSON we
need: meta.filename pinning the basename, sheets=[[<root_uuid>,
""]] binding the schematic root, and stub blocks for board /
schematic / net_settings / erc that KiCad expects to find on the
first GUI load.
- root_sch_writer.write_root_sheet() now accepts an optional
root_uuid so the caller can pass the same uuid into the .kicad_pro
and .kicad_sch (the binding fails silently with mismatched ids).
- CLI gains `--all`: groups SCH/PCB docs by their META.board uuid
(1:1 in EPRO2), strips SCH-/PCB- editor prefixes from titles to
derive a shared project basename, and emits one directory per
BOARD with paired files. BOARDs whose SCH is DELETE_DOC (LCD-BD on
ESP-VoCat) still get a .kicad_pro with sheets:[] + .kicad_pcb so
pcbnew opens cleanly.
ESP-VoCat smoke: 6 boards → 6 project dirs, all pairs validated by
kicad-cli sch erc / pcb export svg. The CoreBoard pro/sch/pcb trio
shares root uuid 366d3e53...c2fccbe4330b end-to-end.
68 → 71 unit tests pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>