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
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
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",