← Commit history

v0.9.166: #31 - load the reverse bridge from KiCad's scripting/plugins dir, the hook that still fires on 10.0.5 (verified live: a probe there ran inside kicad.exe with USER_SITE already correct)

John Lauer ·8fcbb05686 ·1mo ago ·parent 27d1a81
5 files changed +74−7
BRIDGE_VERSION+1−1
@@ -1 +1 @@-0.9.165+0.9.166
adom-bridge-kicad-manifest.json+5−5
@@ -1,15 +1,15 @@ {   "manifest_version": 1,   "name": "kicad",-  "version": "0.9.165",-  "url": "https://wiki.adom.inc/download/adom/kicad-bridge/0.9.165/adom-bridge-kicad-v0.9.165.zip",-  "sha256": "2cb2c8ea5e2f51b818b91a90083c14ed4fd51f26aa181137719f8a70dab06da8",-  "size": 443871,+  "version": "0.9.166",+  "url": "https://wiki.adom.inc/download/adom/kicad-bridge/0.9.166/adom-bridge-kicad-v0.9.166.zip",+  "sha256": "d83c5a35c1ee5995fa078e4b12f484a27b4fc5a671f719e8ba675ac85a471a47",+  "size": 444512,   "verbPrefixes": [     "kicad_"   ],   "healthEndpoint": "/status",-  "released_at": "2026-08-18T12:25:13Z",+  "released_at": "2026-08-18T12:48:46Z",   "hero": "https://wiki.adom.inc/blob/app/kicad-bridge/kicad-hero.png",   "languages": [     "Python",
adom-bridge-kicad-v0.9.166.zipadded
⋯ 1 unchanged line ⋯
bridge.json+1−1
@@ -2,7 +2,7 @@   "manifest_version": 1,   "name": "kicad",   "displayName": "KiCad EDA",-  "version": "0.9.165",+  "version": "0.9.166",   "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_install.py+67
@@ -139,6 +139,55 @@ except Exception: """  +_PLUGIN_DIR_LOADER = """\+\"\"\"adom_bridge_plugin - Adom KiCad bridge loader, KiCad plugin-dir entry.++THE 10.0.5 FIX (issue #31, root-caused 2026-08-18). The bridge used to be loaded+by usercustomize.py, which only runs if the interpreter performs site's+execusercustomize() step. KiCad 10.0.5's GUI stopped doing that, so the reverse+bridge never started and kicad_bridge_status read 0 alive while KiCad sat there+running.++KiCad DOES still import every .py in its scripting/plugins directory at startup -+verified live on 10.0.5: a probe placed here fired inside kicad.exe and reported+site.USER_SITE already pointing at the bridge's deploy directory. So this file is+the reliable entry point, and the payload it loads is unchanged.+\"\"\"+try:+    import os+    import sys++    if not os.environ.get("ADOM_KICAD_BRIDGE_LOADED"):+        os.environ["ADOM_KICAD_BRIDGE_LOADED"] = "1"+        import usercustomize  # noqa: F401 - importing it IS the bootstrap+except Exception:+    try:+        import tempfile+        import traceback+        with open(os.path.join(tempfile.gettempdir(),+                               "adom-kicad-plugin-loader.error.log"), "a") as fh:+            fh.write(traceback.format_exc() + chr(10))+    except Exception:+        pass+"""+++def _kicad_plugin_dirs(version: str):+    """KiCad's own scripting-plugin directories (it imports every .py here at+    startup). %APPDATA%/kicad/<version>/scripting/plugins on Windows."""+    import os as _os+    from pathlib import Path as _P+    appdata = _os.environ.get("APPDATA")+    if not appdata:+        return []+    out = []+    base = _P(appdata) / "kicad"+    for v in ({version} | {d.name for d in base.glob("*") if d.is_dir()}):+        if v:+            out.append(base / v / "scripting" / "plugins")+    return out++ def _std_user_site():     """The interpreter's DEFAULT user-site for KiCad's Python 3.11 on Windows:     %APPDATA%\\Python\\Python311\\site-packages. KiCad 10.0.5 reports this as@@ -346,6 +395,24 @@ def _install_one_version(version: str, version_info: dict) -> dict:     # everything deployed to the Documents user-site is invisible. Deploying the     # same payload to the interpreter's real user-site makes the loader fire     # again; the boot guard keeps it inert in every non-KiCad Python.+    # THE loader that actually fires on 10.0.5: KiCad imports scripting/plugins.+    try:+        pdirs = _kicad_plugin_dirs(str(version or "10.0"))+        wrote = []+        for pdir in pdirs:+            try:+                pdir.mkdir(parents=True, exist_ok=True)+                (pdir / "adom_bridge_plugin.py").write_text(_PLUGIN_DIR_LOADER,+                                                            encoding="utf-8")+                wrote.append(str(pdir))+            except Exception:+                pass+        if wrote:+            report["pluginDirLoaders"] = wrote+            written.append({"name": "adom_bridge_plugin.py", "dest": "; ".join(wrote)})+    except Exception as e:+        report["pluginDirError"] = str(e)+     try:         std_site = _std_user_site()         if std_site and std_site != user_site: