← Commit history

v0.9.102: guardian pre-suppresses ALL visible KiCad windows (0.5s sweep) — closes the free-first-steal hole the 0.9.101 proof run exposed

John Lauer ·aa55a84ffe ·1mo ago ·parent 3743b45
6 files changed +33−8
BRIDGE_VERSION+1−1
@@ -1 +1 @@-0.9.101+0.9.102
adom-bridge-kicad-manifest.json+5−5
@@ -1,15 +1,15 @@ {   "manifest_version": 1,   "name": "kicad",-  "version": "0.9.101",-  "url": "https://wiki.adom.inc/download/adom/kicad-bridge/0.9.101/adom-bridge-kicad-v0.9.101.zip",-  "sha256": "f83d78fbb6d44b93b0c10685cda47ebbda282573105c492d3a088ce07090b21b",-  "size": 393996,+  "version": "0.9.102",+  "url": "https://wiki.adom.inc/download/adom/kicad-bridge/0.9.102/adom-bridge-kicad-v0.9.102.zip",+  "sha256": "6b772fce143ccfa5f180f906cf2df88e80b11c83eeef15c7bde44d8bf4a18441",+  "size": 394342,   "verbPrefixes": [     "kicad_"   ],   "healthEndpoint": "/status",-  "released_at": "2026-08-15T09:56:34Z",+  "released_at": "2026-08-15T09:58:18Z",   "hero": "https://wiki.adom.inc/blob/app/kicad-bridge/kicad-hero.png",   "languages": [     "Python",
adom-bridge-kicad-v0.9.102.zipadded
⋯ 1 unchanged line ⋯
bridge.json+1−1
@@ -2,7 +2,7 @@   "manifest_version": 1,   "name": "kicad",   "displayName": "KiCad EDA",-  "version": "0.9.101",+  "version": "0.9.102",   "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/win_focus.py+25
@@ -229,6 +229,26 @@ def restore_foreground_persistent(hwnd, seconds: float = 6.0, interval: float =     import threading     import time as _t +    def _sweep_suppress():+        """Pre-suppress EVERY visible KiCad top-level window — so a window's+        FIRST self-activation is refused too, not just its repeat offenses.+        (v0.9.102: the 0.9.101 proof run still showed exactly one visible steal+        per fresh window — the free first offense. This closes it.)"""+        try:+            import ctypes as _ct+            WNDENUMPROC = _ct.WINFUNCTYPE(_ct.c_bool, _ct.wintypes.HWND, _ct.wintypes.LPARAM)+            def cb(h, _l):+                try:+                    if _user32.IsWindowVisible(h) and is_kicad_window(h):+                        suppress_activation(h)+                except Exception:+                    pass+                return True+            cbp = WNDENUMPROC(cb)+            _user32.EnumWindows(cbp, 0)+        except Exception:+            pass+     def _loop():         global _guard_count         if _guard_lock:@@ -236,9 +256,14 @@ def restore_foreground_persistent(hwnd, seconds: float = 6.0, interval: float =                 _guard_count += 1         protect = hwnd         deadline = _t.monotonic() + seconds+        tick = 0         try:+            _sweep_suppress()  # pre-suppress what's already up before the verb acts             while _t.monotonic() < deadline:                 try:+                    tick += 1+                    if tick % 5 == 0:+                        _sweep_suppress()   # catch windows CREATED mid-verb (~every 0.5s)                     fg = _user32.GetForegroundWindow()                     if fg and fg != protect:                         if is_kicad_window(fg):
skills/kicad-bridge-test/run_verb_tests.py+1−1
@@ -409,7 +409,7 @@ def main():                          "response_head": json.dumps(r)[:400]}         print(f"  kicad_{verb:24} {'PASS' if passed else 'FAIL'}") -    PHASE3_ORDER = ["launch", "open_board", "open_schematic", "open_symbol_editor",+    PHASE3_ORDER = ["launch", "show_project", "open_board", "open_schematic", "open_symbol_editor",                     "show_schematic", "show_2d_board", "show_symbol", "show_footprint",                     "show_3d_chip", "show_3d_board", "show_library", "state",                     "open_footprint_editor", "open_3d_viewer", "open_editors",