app
Adom Desktop - 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.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
"""Handlers for open_board and open_schematic commands."""
import subprocess
from pathlib import Path
def handle_open_board(kicad_info: dict, args: dict) -> dict:
"""Open a .kicad_pcb file in pcbnew."""
return _open_file(kicad_info, args, "pcbnew_exe", "PCB board")
def handle_open_schematic(kicad_info: dict, args: dict) -> dict:
"""Open a .kicad_sch file in eeschema."""
return _open_file(kicad_info, args, "eeschema_exe", "schematic")
def _open_file(kicad_info: dict, args: dict, exe_key: str, file_type_label: str) -> dict:
if not kicad_info.get("installed"):
return {
"success": False,
"error": "KiCad not installed",
"_hint": "Report to the user and ask them to install KiCad from https://www.kicad.org/download/, then retry.",
}
file_path = args.get("filePath", "")
if not file_path:
return {"success": False, "error": "No filePath specified"}
path = Path(file_path)
if not path.exists():
return {
"success": False,
"error": f"File not found: {file_path}",
"_hint": "The path may exist on Docker but not on the Windows host. Use push_file to copy from Docker first, or verify the host-side path.",
}
exe = kicad_info.get(exe_key)
if not exe or not Path(exe).exists():
return {
"success": False,
"error": f"KiCad executable not found: {exe_key}",
"_hint": "Report to the user and ask them to reinstall KiCad — the installation appears corrupted.",
}
try:
subprocess.Popen(
[exe, str(path)],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
# v1.7.12+: hint nudging the AI toward kicad_lint_board /
# kicad_lint_schematic for unfamiliar files. The lint verbs are
# ~1-3s via kicad-cli and surface DRC/ERC violations + file-format
# issues BEFORE the GUI even tries to render — much faster than
# screenshotting a confused GUI to figure out what went wrong.
is_pcb = "pcbnew" in exe_key
lint_verb = "kicad_lint_board" if is_pcb else "kicad_lint_schematic"
return {
"success": True,
"output": f"Launched {file_type_label} editor with {path.name}",
"_hint": (
f"GUI launched. For unfamiliar files (ones you didn't generate / haven't validated), "
f"prefer running `{lint_verb}` FIRST. It uses kicad-cli to give you structured "
f"DRC/ERC + file-format info in ~1-3s, much faster + more reliable than recovering "
f"from a confused GUI via screenshots. If the GUI shows a modal dialog (file-version "
f"upgrade prompt, missing-symbol warning, recovery prompt), use kicad_window_info → "
f"kicad_screenshot_all → kicad_send_key to handle it; or close + retry after lint."
),
}
except Exception as e:
return {
"success": False,
"error": f"Failed to launch: {e}",
"_hint": "Call close_kicad with {\"force\": true} to clear any stuck processes, then retry.",
}