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
Update 4 file(s)
4 files changed
+48−9
BRIDGE_VERSION+1−1@@ -1 +1 @@-0.9.207+0.9.208
adom-bridge-kicad-manifest.json+5−5@@ -1,15 +1,15 @@ { "manifest_version": 1, "name": "kicad",- "version": "0.9.207",- "url": "https://wiki.adom.inc/download/adom/kicad-bridge/0.9.207/adom-bridge-kicad-v0.9.207.zip",- "sha256": "060fb8c7fb95348be3b82e9bef760019c98da26efb9f6d0fb7171236a1455fda",- "size": 476698,+ "version": "0.9.208",+ "url": "https://wiki.adom.inc/download/adom/kicad-bridge/0.9.208/adom-bridge-kicad-v0.9.208.zip",+ "sha256": "45431a4e129667b0daba2dbdd923361989ddc80b9d14c6739db117f36c2885c5",+ "size": 477320, "verbPrefixes": [ "kicad_" ], "healthEndpoint": "/status",- "released_at": "2026-08-20T13:05:00Z",+ "released_at": "2026-08-20T13:35:00Z", "hero": "https://wiki.adom.inc/blob/app/kicad-bridge/kicad-hero.png", "languages": [ "Python",
bridge.json+1−1@@ -2,7 +2,7 @@ "manifest_version": 1, "name": "kicad", "displayName": "KiCad EDA",- "version": "0.9.207",+ "version": "0.9.208", "description": "Reverse bridge for KiCad \u2014 board/schematic introspection, lint via kicad-cli, plugin install, multi-instance probe, in-process DRC.", "homepage": "https://wiki.adom.inc/adom/adom-bridge", "author": "Adom Inc.",
handlers/open_footprint_editor.py+41−2@@ -302,6 +302,38 @@ def _get_footprint_editor_title() -> str: ++def _library_says(kicad_info: dict, library: str, wanted: str) -> dict:+ """What does the library ACTUALLY contain, and is `wanted` in it?++ Wiki issue #42 item 2: three footprints failed to load every time, and the+ error could only say "didn't load in the background" - which cannot tell a+ navigation bug from a name that is not in the library. The listing is on+ disk and costs nothing to read, so the failure should answer that itself+ instead of handing the question back to the caller."""+ try:+ from handlers.install_footprint import handle_list_footprints+ lst = handle_list_footprints(kicad_info, {"library": library} if library else {})+ if not lst.get("success"):+ return {}+ names = []+ for _lib, meta in (lst.get("libraries") or {}).items():+ names.extend(meta.get("footprints") or [])+ if not names:+ return {}+ low = (wanted or "").lower()+ exact = any(n.lower() == low for n in names)+ near = []+ if not exact and low:+ near = [n for n in names if low in n.lower() or n.lower() in low]+ if not near:+ import difflib+ near = difflib.get_close_matches(wanted, names, n=3, cutoff=0.6)+ return {"existsInLibrary": exact, "libraryCount": len(names),+ "closestMatches": near[:3]}+ except Exception:+ return {}+ def _parse_fp_title(title: str) -> tuple: """Split a Footprint Editor title into (library, footprint). @@ -856,8 +888,15 @@ def handle_open_footprint_editor(kicad_info: dict, args: dict) -> dict: return { "success": False, "editorOpened": True, "footprintLoaded": False, "attempts": 2,- "error": f"Footprint Editor open but '{search_text}' didn't load in the background "- f"after two attempts (title: {_get_footprint_editor_title() or 'unknown'})",+ **({"library": _lib_says} if (_lib_says := _library_says(+ kicad_info, library_name, footprint_name or search_text)) else {}),+ "error": (f"Footprint Editor open but '{search_text}' didn't load in the background "+ f"after two attempts (title: {_get_footprint_editor_title() or 'unknown'})"+ + ("" if _lib_says.get("existsInLibrary", True) else+ f". NOTE: '{search_text}' is NOT in that library - it has "+ f"{_lib_says.get('libraryCount')} footprint(s)"+ + (f", closest: {', '.join(_lib_says.get('closestMatches') or [])}"+ if _lib_says.get("closestMatches") else "") + ".")), "_hint": ("Two background attempts did not confirm, so a third is unlikely to help - " "check the footprint exists in this library (kicad_list_footprints). " "The keystroke fallback is off by default (it must foreground the window — "