← Commit history

Update 4 file(s)

John Lauer ·5acffa0aa9 ·1mo ago ·parent 5661d72
4 files changed +34−11
BRIDGE_VERSION+1−1
@@ -1 +1 @@-0.9.197\ No newline at end of file+0.9.198\ 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.197",-  "url": "https://wiki.adom.inc/download/adom/kicad-bridge/0.9.197/adom-bridge-kicad-v0.9.197.zip",-  "sha256": "fc2b6091f00d477824d025f61cc072367fc8ea95ec396bc806ae2fb9dcbc79d5",-  "size": 467545,+  "version": "0.9.198",+  "url": "https://wiki.adom.inc/download/adom/kicad-bridge/0.9.198/adom-bridge-kicad-v0.9.198.zip",+  "sha256": "f29948616354a5a2caa53a9a7ad2e3df277e6cfea33ff2cd075137f08a39363d",+  "size": 468068,   "verbPrefixes": [     "kicad_"   ],   "healthEndpoint": "/status",-  "released_at": "2026-08-20T00:55:00Z",+  "released_at": "2026-08-20T01:05: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.197",+  "version": "0.9.198",   "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.",
server.py+27−4
@@ -103,6 +103,12 @@ BRIDGE_VERSION = _read_bridge_version() # already knows the verb name and owns the clock, so it stamps the terminal # progress frame (percent 100 + the real elapsed) and feeds this machine's # rolling history, which is what makes later estimates "measured".+# A dialog only counts as BLOCKING once it has survived this long: KiCad throws+# transient progress windows ("Load PCB") that are gone before a human could+# read them, and calling those "waiting for you" is a lie that stops the bar.+_DIALOG_BLOCK_AFTER_SEC = 3.0+_DIALOG_FIRST_SEEN: dict = {}+ _PHASES = {     "launch": "cold_start", "show_symbol": "show_symbol",     "show_footprint": "show_footprint", "show_3d_chip": "show_3d_chip",@@ -564,14 +570,31 @@ def _handle_progress(kicad_info: dict, args: dict) -> dict:     if frames:         try:             from handlers.close_windows import _win_scan_kicad_dialogs+            now = time.time()+            live_hwnds = set()+            blocker = None             for d in (_win_scan_kicad_dialogs(kicad_info) or []):                 if not d.get("isDialog"):                     continue-                what = (d.get("title") or "").strip() or "a KiCad dialog"+                h = d.get("hwnd")+                live_hwnds.add(h)+                first = _DIALOG_FIRST_SEEN.setdefault(h, now)+                # PERSISTENCE is what separates "you must act" from "KiCad is+                # busy". The first cut reported blockedBy for ANY dialog and+                # promptly claimed "waiting for you: Load PCB" - KiCad's own+                # transient progress window, which nobody had to touch. A false+                # blockedBy is worse than none: it stops the bar AND sends the+                # user hunting for a prompt that already closed itself. A real+                # prompt sits there until a human deals with it, so require the+                # SAME dialog to still be up a few seconds later.+                if now - first >= _DIALOG_BLOCK_AFTER_SEC and blocker is None:+                    blocker = (d.get("title") or "").strip() or "a KiCad dialog"+            for stale in [h for h in _DIALOG_FIRST_SEEN if h not in live_hwnds]:+                _DIALOG_FIRST_SEEN.pop(stale, None)+            if blocker:                 for f in frames:-                    f["blockedBy"] = what-                    f["stepLabel"] = f"waiting for you: {what}"-                break+                    f["blockedBy"] = blocker+                    f["stepLabel"] = f"waiting for you: {blocker}"         except Exception:             pass     return {