app
KiCad - the KiCad Bridge
Public Made by Adomby adom
Drive your own KiCad from an AI, in the background: open every editor, read the whole board as data (the EDA Bridge Standard board model), stack-up, part heights, netlists, place, route, pour, DRC and exports.
← Commit history
Publish 1.0.11
3 files changed
+23−2
package.json+1−1@@ -1,6 +1,6 @@ { "slug": "adom-desktop-kicad-bridge",- "version": "1.0.10",+ "version": "1.0.11", "type": "app", "description": "KiCad bridge for Adom Desktop.", "tags": [
page.json+1−1@@ -4,7 +4,7 @@ "slug": "adom-desktop-kicad-bridge", "title": "Adom Desktop - KiCad Bridge", "brief": "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.",- "version": "1.0.10",+ "version": "1.0.11", "tags": [ "kicad", "pcb",
skills/kicad-bridge-dev/SKILL.md+21@@ -35,6 +35,27 @@ of it) the dispatcher: focus back. Uses **AttachThreadInput** so the cross-process SetForegroundWindow actually sticks (a plain call from a background process is blocked by the foreground lock). The response carries `_userFocusRestored: true/false`.+4. `win_focus.restore_foreground_persistent(user_hwnd, seconds=…)` — a daemon thread that keeps+ re-restoring the user for a few seconds. **This is the part that actually works** — a one-shot+ restore (step 3 alone) is NOT enough, because KiCad activates its window *asynchronously, a beat+ after the handler returns.* Two distinct cases, two durations (see `_SPAWNS_WINDOW` block):+ - **Launched editors** (`open_board`/`open_schematic`/`open_symbol_editor` → a fresh+ pcbnew/eeschema via `subprocess.Popen`): pass `win_focus.background_startupinfo()` as+ `startupinfo=` so the process shows its window with `SW_SHOWNOACTIVATE` (opens behind), **and**+ a **6s** persistent restore for the one late self-activation. Verified: window lands at z-index 1,+ right behind the user's z-0 window.+ - **In-process child windows** (the **3D viewer** — pcbnew *creates and re-raises* it repeatedly+ while it renders the board, over several seconds): `STARTUPINFO` can't touch it (no new process)+ and a 6s restore expires mid-render, so it needs a longer **16s** restore+ (`open_3d_viewer`/`place_footprint`). Don't assume one restore duration fits all — match it to how+ long the window keeps re-raising.++**Verifying background behavior (do NOT trust `GetForegroundWindow` via `run_script`):** measuring+foreground *from* an AD `run_script` is unreliable — the measuring PowerShell/conhost briefly *becomes*+the foreground (you read `''` or itself), and on some machines `run_script` just times out at 75s. Use+**`desktop_list_windows`** (AD-core, no bridge, returns top-level windows in **EnumWindows / top-of-Z-order+first**) and compare the z-index of the KiCad window vs the user's window. If the user's window has a+lower index than every KiCad window, it opened in the background. This is the reliable, non-perturbing test. **Mid-operation matters too, not just the end state.** Restoring focus *after* still lets a window FLASH forward mid-verb, which the user sees and hates. So the handlers themselves must