app
KiCad - the KiCad Bridge
Public Made by Adomby adom
Reference implementation of the KiCad bridge: multi-instance Python server, forward path via kicad-cli, reverse path via in-process plugin. Most complex of the three bundled bridges.
← Commit history
0.9.348 notes; runner: heal after installs, KiCad dialogs are not foreground victims
2 files changed
+22−3
RELEASE_NOTES.md+14@@ -10,6 +10,20 @@ unnamed. These entries were reconstructed after the fact from the work they contain, which is exactly the situation the mandatory-notes gate now prevents. Treat them as accurate but secondhand. +## 0.9.348 (2026-09-08 20:32 UTC)++Focus guardian identity survives hwnd reuse; editors spawn without activation (pre-promotion run findings)++## 0.9.348 (2026-09-08): editors launched by open_board/open_schematic start without activation++- The focus guardian's "push a KiCad window behind the user once" now keys on (hwnd, pid) and expires+ closed windows: Windows recycles hwnd numbers, so a new editor could inherit an already-pushed number+ and never be pushed at all. The push stays one per window (John's rule). Editors opened by+ open_board/open_schematic are spawned with SW_SHOWNOACTIVATE like kicad.exe. Measured on an idle+ ConfRoomROG (no user input for minutes): a new editor still ends on top, because Windows grants a+ new process the foreground once the foreground lock timeout has expired; with a user active Windows+ blocks it. Not new behaviour; recorded here so the pre-promotion runner reading is understood.+ ## 0.9.347 (2026-09-07 19:10 UTC) kicad_close honours unsaved work (#84); verified footprint rescan (#51)
skills/kicad-bridge-test/run_verb_tests.py+8−3@@ -113,8 +113,9 @@ def matrix(w: dict) -> dict: "plugin_diagnose": dict(phase=1, args={}), "pcm_list": dict(phase=1, args={}), "ipc_api": dict(phase=1, args={}, note="READ ONLY here: no enable arg, so nothing is written"),- "adom_library_heal": dict(phase=1, args={"mode": "prune", "dryRun": True},- note="SAFETY: dryRun only; reports what a prune would do"),+ "adom_library_heal": dict(phase=4.5, args={"mode": "prune", "dryRun": True},+ note="SAFETY: dryRun only; after the installs, because a fresh box has no Adom "+ "library to prune yet (winvm 2026-09-08)"), # ---- phase 2: headless exports on the sample board (kicad-cli) "extract_netlist": dict(phase=2, args={"filePath": S, "includeNodes": False}, timeout=120), "analyze_connections": dict(phase=2, args={"filePath": S}, timeout=120),@@ -415,7 +416,11 @@ def main(): top = next((x for x in ws if x.get("z") == 0), None) title = (top or {}).get("title", "") if any(k in title for k in _kw):- had_victim = bool(before) and not any(k in before for k in _kw) and before not in ("Program Manager",)+ _kicad_dialogs = ("Information", "Confirmation", "Save Changes?", "KiCad Setup", "Load ", "Loading",+ "Progress", "Warning", "Error")+ had_victim = (bool(before) and not any(k in before for k in _kw)+ and not any(before.startswith(k) for k in _kicad_dialogs)+ and before not in ("Program Manager",)) if had_victim: fg_violations.append({"after_verb": verb, "foreground": title, "before": before}) if verb in results and results[verb]["result"] == "PASS":