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.63: demo cold-start fix — warm eeschema first (Symbol Editor is hosted in it) + one retry per step
3 files changed
+34−3
adom-bridge-kicad-manifest.json+3−3@@ -3,13 +3,13 @@ "name": "kicad", "version": "0.9.63", "url": "https://wiki.adom.inc/download/adom/adom-desktop-kicad-bridge/0.9.63/adom-bridge-kicad-v0.9.63.zip",- "sha256": "c2c1249e3c49c9668ecc59397fdb88f87944406a7c595e554b42cf727b8d9264",- "size": 351315,+ "sha256": "a9c4fee2d1b038912c6f91b0569c793cd2b1667a1b8a4b2a712230304e80070c",+ "size": 351891, "verbPrefixes": [ "kicad_" ], "healthEndpoint": "/status",- "released_at": "2026-07-20T11:09:33Z",+ "released_at": "2026-07-20T11:25:35Z", "hero": "https://wiki.adom.inc/blob/app/adom-desktop-kicad-bridge/kicad-hero.png", "languages": [ "Python",
adom-bridge-kicad-v0.9.63.zip⋯ 1 unchanged line ⋯
handlers/demo.py+31@@ -263,6 +263,27 @@ def _prepare(kicad_info: dict) -> dict: return out +def _warm_kicad(kicad_info: dict, prep: dict) -> dict:+ """Get KiCad up and settled BEFORE the tour's first beat.++ The demo is by definition the cold-start case: on a fresh machine nothing is+ running, and `open_symbol_editor` has to launch the project manager, post a+ WM_COMMAND and hope the Symbol Editor appears within its 10 s budget. On a+ cold KiCad (splash + loading every symbol library) it frequently does not —+ the tour's very first step then fails, which is the worst possible demo.++ Opening the demo SCHEMATIC first fixes it twice over: it launches eeschema,+ and Symbol Editor is hosted INSIDE eeschema, so the subsequent open takes the+ fast in-process plugin pathway instead of the fragile cold WM_COMMAND one.+ Windows still open in the background; this only costs a few seconds.+ """+ import time+ r = handle_open_schematic(kicad_info, {"filePath": prep["schematic"]})+ if r.get("success"):+ time.sleep(8) # let eeschema finish loading its libraries+ return {"warmed": bool(r.get("success")), "raw": r}++ def _run_step(kicad_info: dict, step: str, prep: dict) -> dict: """Run one tour step. Returns narration-ready info, never raises.""" has3d = bool((prep.get("models3d") or {}).get("soic8"))@@ -376,10 +397,19 @@ def handle_demo(kicad_info: dict, args: dict) -> dict: return {"success": False, "error": f"unknown step '{step}'", "data": {"validSteps": STEPS}} prep = _prepare(kicad_info)+ # Cold-start warm-up: launches eeschema so the editor steps take the fast+ # in-process pathway instead of a cold WM_COMMAND that times out.+ prep["warm"] = _warm_kicad(kicad_info, prep)++ import time steps = [step] if step else STEPS results, failed = [], [] for s in steps: r = _run_step(kicad_info, s, prep)+ if not r.get("ok"): # one retry — a cold editor often misses its first budget+ time.sleep(3)+ r = _run_step(kicad_info, s, prep)+ r["retried"] = True r["step"] = s results.append(r) if not r.get("ok"):@@ -397,6 +427,7 @@ def handle_demo(kicad_info: dict, args: dict) -> dict: "models3d": prep.get("models3d"), "warnings": prep.get("warnings"), "installedKiCadJustNow": installed_now,+ "warmedUp": (prep.get("warm") or {}).get("warmed"), "screenshotVerb": "kicad_screenshot_all", "cleanup": "kicad_close {\"force\":true}", },