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
+37−10
BRIDGE_VERSION+1−1@@ -1 +1 @@-0.9.213+0.9.214
adom-bridge-kicad-manifest.json+5−5@@ -1,15 +1,15 @@ { "manifest_version": 1, "name": "kicad",- "version": "0.9.213",- "url": "https://wiki.adom.inc/download/adom/kicad-bridge/0.9.213/adom-bridge-kicad-v0.9.213.zip",- "sha256": "ae143664eab5074d0eef9c509936f08f0283f1de88f8e445a7a280897befb10b",- "size": 482152,+ "version": "0.9.214",+ "url": "https://wiki.adom.inc/download/adom/kicad-bridge/0.9.214/adom-bridge-kicad-v0.9.214.zip",+ "sha256": "4531cb0b703a69aeeafa6ed54662557b05a6a487578d04afca63a1cfa7b571d7",+ "size": 482513, "verbPrefixes": [ "kicad_" ], "healthEndpoint": "/status",- "released_at": "2026-08-20T15:55:00Z",+ "released_at": "2026-08-20T16:05: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.213",+ "version": "0.9.214", "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.",
plugin_payload/adom_bridge.py+30−3@@ -2808,6 +2808,30 @@ def _ui_wm_command(frame_index: int, menu_id: int) -> dict: # --- request dispatcher ---------------------------------------------------- ++class _ModuleFpTable:+ """Adapter over KiCad 10's module-level footprint functions.++ KiCad 10 has no footprint-table OBJECT exposed to Python - it has+ pcbnew.GetFootprintLibraries() / FootprintEnumerate() / FootprintLoad().+ This presents them with the same three methods the probe uses, so the+ probe's logic stays one shape across KiCad versions."""++ def __init__(self, mod):+ self._m = mod+ # Fail construction if this build does not actually have them, so the+ # caller moves on to the next candidate instead of failing later.+ self._m.GetFootprintLibraries++ def GetLogicalLibs(self):+ return list(self._m.GetFootprintLibraries())++ def FootprintEnumerate(self, library, _best_efforts=False):+ return list(self._m.FootprintEnumerate(library))++ def FootprintLoad(self, library, footprint):+ return self._m.FootprintLoad(library, footprint)+ def _ui_probe_footprint(library: str, footprint: str) -> dict: """Ask KICAD ITSELF whether it can see and load this footprint. @@ -2833,10 +2857,13 @@ def _ui_probe_footprint(library: str, footprint: str) -> dict: # the next attempt is informed rather than another guess. tbl, via, errs = None, None, [] for name, getter in (+ # KiCad 10 exposes these as MODULE-LEVEL functions rather than a table+ # object; the previous guesses failed and the probe's own apiCandidates+ # report named these, which is how they got here rather than by guess.+ ("module:GetFootprintLibraries", lambda: _ModuleFpTable(pcbnew)), ("GetGlobalFootprintTable", lambda: pcbnew.GetGlobalFootprintTable()), ("FP_LIB_TABLE.GetGlobalLibTable", lambda: pcbnew.FP_LIB_TABLE.GetGlobalLibTable()), ("GetFootprintLibraryTable", lambda: pcbnew.GetFootprintLibraryTable()),- ("Frame.Prj.PcbFootprintLibs", lambda: pcbnew.GetBoard().GetProject().PcbFootprintLibs()), ): try: tbl = getter()@@ -2851,8 +2878,8 @@ def _ui_probe_footprint(library: str, footprint: str) -> dict: try: out["apiCandidates"] = sorted( n for n in dir(pcbnew)- if ("footprintlib" in n.lower() or "fp_lib" in n.lower()- or "footprinttable" in n.lower()))[:20]+ if n.lower().startswith("footprint") or "footprintlib" in n.lower()+ or "fp_lib" in n.lower())[:30] except Exception: pass out["error"] = "could not reach KiCad's footprint library table on this build"