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 6 file(s)
6 files changed
+67−16
BRIDGE_VERSION+1−1@@ -1 +1 @@-0.9.191+0.9.192
adom-bridge-kicad-manifest.json+5−5@@ -1,15 +1,15 @@ { "manifest_version": 1, "name": "kicad",- "version": "0.9.191",- "url": "https://wiki.adom.inc/download/adom/kicad-bridge/0.9.191/adom-bridge-kicad-v0.9.191.zip",- "sha256": "5ac6c8bcff75ef1f8a701ff2b70b21e2d1255c118d16bc1265f6c02b8fcd956e",- "size": 459559,+ "version": "0.9.192",+ "url": "https://wiki.adom.inc/download/adom/kicad-bridge/0.9.192/adom-bridge-kicad-v0.9.192.zip",+ "sha256": "13bb28e8564364c640416ee08911286a6423213cead03066b378a186394108e5",+ "size": 460359, "verbPrefixes": [ "kicad_" ], "healthEndpoint": "/status",- "released_at": "2026-08-19T21:14:02Z",+ "released_at": "2026-08-19T21:40: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.191",+ "version": "0.9.192", "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/install_symbol.py+22−1@@ -117,12 +117,25 @@ def handle_install_symbol(kicad_info: dict, args: dict) -> dict: output_parts = [ f"Symbol(s) {', '.join(added_names)} added to '{ADOM_LIB_NAME}' library" ]++ # A caller who names a library means it. Every Adom symbol lives in the one+ # global Adom library by design, so we cannot honour another name -- but+ # silently returning libraryName:"Adom" for a request that said "AdomTest"+ # hands the caller a success it did not ask for. Say so out loud instead.+ requested_lib = (args.get("libraryName") or "").strip()+ ignored_lib = requested_lib and requested_lib != ADOM_LIB_NAME if editor_opened: output_parts.append(f"Symbol Editor: {editor_output}") elif open_editor: output_parts.append(f"Symbol Editor: {editor_output}") - return {+ if ignored_lib:+ output_parts.append(+ f"NOTE: libraryName '{requested_lib}' was ignored - every Adom symbol "+ f"installs into the single global '{ADOM_LIB_NAME}' library"+ )++ out = { "success": True, "output": " | ".join(output_parts), "installedPath": lib_path,@@ -130,3 +143,11 @@ def handle_install_symbol(kicad_info: dict, args: dict) -> dict: "libraryName": ADOM_LIB_NAME, "editorOpened": editor_opened, }+ if ignored_lib:+ out["ignoredArgs"] = {"libraryName": requested_lib}+ out["_hint"] = (+ f"libraryName is not honoured by this verb: all Adom symbols live in "+ f"'{ADOM_LIB_NAME}'. Drop the argument, or use kicad_install_library "+ f"if you genuinely need a separate library file."+ )+ return out
handlers/open_footprint_editor.py+16−2@@ -776,12 +776,26 @@ def handle_open_footprint_editor(kicad_info: dict, args: dict) -> dict: # BACKGROUND-FIRST (John, 2026-08-14): the win32 tier above is the background # path; the SendKeys/Ctrl+Shift+E fallback needs a foregrounded window (rude, # and leaks keys to the user's window if we DON'T foreground). Opt-in only.+ # 0.9.192: retry here instead of telling the caller to. The first attempt is+ # what warms the library tree, so a second one is a genuinely different shot,+ # not a repeat of a hopeless call. Same change as open_symbol_editor.+ if _background_navigate_win32_fp(fp_hwnd, _filter, _verify):+ return {+ "success": True,+ "output": f"Footprint '{search_text}' loaded (background win32 path, 2nd attempt): "+ f"{_get_footprint_editor_title()}",+ "via": "win32-background",+ "attempts": 2,+ }+ if not args.get("allowFocusSteal"): return { "success": False, "editorOpened": True, "footprintLoaded": False,+ "attempts": 2, "error": f"Footprint Editor open but '{search_text}' didn't load in the background "- f"(title: {_get_footprint_editor_title() or 'unknown'})",- "_hint": ("Background load unconfirmed. Retry once (the win32 tier usually lands warm). "+ f"after two attempts (title: {_get_footprint_editor_title() or 'unknown'})",+ "_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 — " "rude while you type); pass allowFocusSteal:true to accept a focus grab, or " "foreground:true to bring the editor to you."),
handlers/open_symbol_editor.py+22−6@@ -642,16 +642,32 @@ def handle_open_symbol_editor(kicad_info: dict, args: dict) -> dict: # background path. The PowerShell SendKeys fallback below fires GLOBAL # keystrokes that need the window foregrounded — which would type into the # USER's active window if we don't steal focus, and stealing focus is rude.- # So it is OPT-IN only ({"allowFocusSteal":true}); by default we return the- # honest failure and let the caller retry (the win32 tier usually lands on a- # 2nd try once eeschema's tree is warm).+ # So it is OPT-IN only ({"allowFocusSteal":true}); by default we return an+ # honest failure rather than grabbing the user's keyboard.+ # 0.9.192: the old code told the CALLER to "retry this same call, the win32+ # tier usually lands 2nd try once the tree is warm". If we know a second+ # attempt usually works, making the caller pay for it is just passing our+ # own retry loop out through the API. Do it here, once, before failing.+ # The first attempt is what warms the tree, so this is a fresh-tree retry,+ # not a duplicate of a hopeless call.+ if _background_navigate_win32(sym_hwnd, _filter, _verify):+ return {+ "success": True,+ "output": f"Symbol '{search_text}' loaded (background win32 path, 2nd attempt): "+ f"{_get_symbol_editor_title()}",+ "via": "win32-background",+ "attempts": 2,+ }+ if not args.get("allowFocusSteal"): return { "success": False, "editorOpened": True, "symbolLoaded": False,+ "attempts": 2, "error": f"Symbol Editor open but '{search_text}' didn't load in the background "- f"(title: {_get_symbol_editor_title() or 'unknown'})",- "_hint": ("The background load didn't confirm. Retry this same call (the win32 tier "- "usually lands 2nd try once the library tree is warm). The keystroke fallback "+ f"after two attempts (title: {_get_symbol_editor_title() or 'unknown'})",+ "_hint": ("Two background attempts did not confirm, so a third is unlikely to "+ "help - check that the symbol really exists in this library "+ "(kicad_list_symbols). The keystroke fallback " "is disabled by default because it needs to foreground the window (rude while " "you're typing) — pass allowFocusSteal:true ONLY if you accept a focus grab, " "or foreground:true to bring the editor to you and load it yourself."),