← Commit history

v0.9.77: open_symbol_editor honors symbolName/libraryName (#20) — waits for cold-start plugin, library-qualified filter, verified load with honest success:false

John Lauer ·096f46c06b ·2mo ago ·parent 48a72ee
6 files changed +54−23
BRIDGE_VERSION+1−1
@@ -1 +1 @@-0.9.76+0.9.77
adom-bridge-kicad-manifest.json+5−5
@@ -1,15 +1,15 @@ {   "manifest_version": 1,   "name": "kicad",-  "version": "0.9.76",-  "url": "https://wiki.adom.inc/download/adom/kicad-bridge/0.9.76/adom-bridge-kicad-v0.9.76.zip",-  "sha256": "cb2d1a1388017d5b6f5bf14c9720fc079af175c1480f7080e648c19efe2bd460",-  "size": 373323,+  "version": "0.9.77",+  "url": "https://wiki.adom.inc/download/adom/kicad-bridge/0.9.77/adom-bridge-kicad-v0.9.77.zip",+  "sha256": "b0a50d1262eb84074fba0ed4d3378668f2d8568f05af455fa57d20f91b3c68c4",+  "size": 374204,   "verbPrefixes": [     "kicad_"   ],   "healthEndpoint": "/status",-  "released_at": "2026-08-13T23:46:06Z",+  "released_at": "2026-08-14T01:28:56Z",   "hero": "https://wiki.adom.inc/blob/app/kicad-bridge/kicad-hero.png",   "languages": [     "Python",
adom-bridge-kicad-v0.9.77.zipadded
⋯ 1 unchanged line ⋯
bridge.json+1−1
@@ -2,7 +2,7 @@   "manifest_version": 1,   "name": "kicad",   "displayName": "KiCad EDA",-  "version": "0.9.76",+  "version": "0.9.77",   "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_symbol_editor.py+45−14
@@ -152,21 +152,36 @@ def _get_symbol_editor_title() -> str:         return ""  -def _plugin_background_load(symbol_name: str) -> dict:+def _plugin_background_load(symbol_name: str, library_name: str = "",+                            wait_plugin_s: float = 0.0) -> dict:     """v0.9.74: background canvas-load via the in-process plugin (payload 0.9.1+).      Two-hop filter->settle->activate inside the plugin, zero focus/keyboard     theft (John's no-foreground mandate). Uses bridge_client's discovery to find     the live eeschema instance. {'loaded': False, ...} on any failure so the     caller can fall through to the legacy paths.++    v0.9.77 (#20): `wait_plugin_s` polls for the plugin to COME ALIVE — on a+    cold-started eeschema the plugin needs a few seconds to bind, and giving up+    on the first probe was the main reason a requested symbol never loaded.+    `library_name` narrows the LIB_TREE filter ("Device R" instead of just "R")+    so a short symbol name doesn't strand the selection on the wrong match.     """     try:         from .bridge_client import _resolve_plugin, call as _plugin_call-        info, err = _resolve_plugin("eeschema")-        if err is not None or not info:-            return {"loaded": False, "_error": "no live eeschema plugin"}+        deadline = time.monotonic() + max(0.0, wait_plugin_s)+        info = None+        while True:+            info, err = _resolve_plugin("eeschema")+            if err is None and info:+                break+            if time.monotonic() >= deadline:+                return {"loaded": False, "_error": "no live eeschema plugin"}+            time.sleep(1.0)+        filter_text = f"{library_name} {symbol_name}".strip() if library_name else symbol_name         return _plugin_call(info["port"], "select_and_load_symbol",-                            {"symbolName": symbol_name}, timeout=15.0) or {"loaded": False}+                            {"symbolName": filter_text, "libraryName": library_name},+                            timeout=15.0) or {"loaded": False}     except Exception as e:  # pylint: disable=broad-except         return {"loaded": False, "_error": f"{type(e).__name__}: {e}"} @@ -444,11 +459,14 @@ def handle_open_symbol_editor(kicad_info: dict, args: dict) -> dict:     # v0.9.74: FIRST try the plugin's background canvas-load (payload 0.9.1's     # two-hop filter->settle->activate) — zero focus/keyboard theft. The PS     # navigate below is the fallback when no plugin instance is alive.-    _pl = _plugin_background_load(search_text)+    # v0.9.77 (#20): wait up to 12s for the plugin on a cold-started eeschema —+    # first-probe give-up was why symbolName silently produced an empty editor.+    _verify = (symbol_name or search_text).lower()+    _pl = _plugin_background_load(search_text, library_name, wait_plugin_s=12.0)     if str(_pl.get("loaded")) in ("True", "unverified"):         time.sleep(0.6)         _title = _get_symbol_editor_title() if "_get_symbol_editor_title" in globals() else ""-        if _pl.get("loaded") is True or (search_text.lower() in (_title or "").lower()):+        if _pl.get("loaded") is True or (_verify in (_title or "").lower()):             return {                 "success": True,                 "output": f"Symbol '{search_text}' loaded (background plugin path): {_title or _pl.get('frameTitle','')}",@@ -485,16 +503,29 @@ def handle_open_symbol_editor(kicad_info: dict, args: dict) -> dict:                 "output": f"Symbol Editor loaded: {nav_result2['title']}",             }         else:+            # #20: the caller asked for a SPECIFIC symbol and it is not loaded —+            # that is a failure of the request, not a success. The editor itself+            # is open (editorOpened) so the caller can decide to retry or hand off.             return {-                "success": True,-                "output": f"Symbol Editor opened and searched for '{search_text}'. "-                          f"Use Ctrl+Shift+E to load the symbol if it didn't auto-load.",+                "success": False,+                "editorOpened": True,+                "symbolLoaded": False,+                "error": f"Symbol Editor opened but '{search_text}' did not load "+                         f"(title: {_get_symbol_editor_title() or 'unknown'})",+                "pathwaysTried": pathways_tried + ["plugin-background", "ps-navigate", "ps-navigate-retry"],+                "_hint": ("Both load paths ran without confirming the symbol. If eeschema just "+                          "cold-started, its plugin may still be binding — retry this same call "+                          "(the plugin path is waited on and usually succeeds second time). Verify "+                          "the symbol exists: the title staying '[no symbol loaded]' with a valid "+                          "name usually means the library/symbol pair doesn't match."),             }     else:         # Error from the script-        _force_foreground(sym_hwnd)         return {-            "success": True,-            "output": f"Symbol Editor opened but navigation failed: {nav_result.get('error', 'unknown')}. "-                      f"Search for '{search_text}' manually.",+            "success": False,+            "editorOpened": True,+            "symbolLoaded": False,+            "error": f"Symbol Editor opened but navigation errored: {nav_result.get('error', 'unknown')}",+            "pathwaysTried": pathways_tried + ["plugin-background", "ps-navigate:error"],+            "_hint": f"Retry once; if it persists, kicad_screenshot_all shows the editor state. Requested: '{search_text}'.",         }
server.py+2−2
@@ -207,9 +207,9 @@ _VERB_CATALOG = {         "related": ["kicad_run_erc", "kicad_export_bom_csv", "kicad_screenshot_all", "kicad_close"],         "pitfalls": ["filePath must be ABSOLUTE", "open the top-level .kicad_sch, not a sub-sheet, to load the whole design"]},     "open_symbol_editor": {"summary": "Open the Symbol Editor (optionally at a symbol).", "long": True,-        "hint": "Opens the Symbol Editor; pass library/symbol to jump straight to one.",+        "hint": "Opens the Symbol Editor; pass symbolName (+ libraryName to disambiguate short names) to load that symbol into the canvas. v0.9.77: the load is VERIFIED — if the requested symbol didn't load you get success:false with editorOpened:true, not a silent empty editor.",         "related": ["kicad_install_symbol", "kicad_close_symbol_editor", "kicad_screenshot_all"],-        "pitfalls": ["the symbol must already be in an installed sym-lib-table library (install_symbol first)"]},+        "pitfalls": ["the symbol must already be in an installed sym-lib-table library (install_symbol first)", "cold-started eeschema needs a few seconds for its plugin to bind — the verb waits, but a retry after success:false usually lands"]},     "open_footprint_editor": {"summary": "Open the Footprint Editor (optionally at a footprint).", "long": True,         "hint": "Opens the Footprint Editor; pass library/footprint to jump to one.",         "related": ["kicad_install_footprint", "kicad_close_footprint_editor", "kicad_screenshot_all"],