← Commit history
BRIDGE_VERSION+1−1
@@ -1 +1 @@-0.9.191+0.9.192\ No newline at end of file
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."),