name: adom-desktop-kicad public: true description: "Launch and drive KiCad on the user's laptop (KiCad 7/8/9/10 supported, multi-version side-by-side) from this container via the adom-desktop CLI. Open schematics/boards/symbols/footprints, run DRC, install sym-lib-table / fp-lib-table libraries, show the 3D viewer, capture KiCad window screenshots, send keyboard shortcuts and click coordinates. Trigger words: kicad, open schematic, open board, open pcb, open symbol, open footprint, KiCad symbol editor, KiCad footprint editor, KiCad 3D viewer, run DRC, install KiCad library, sym-lib-table, fp-lib-table, KiCad screenshot, kicad_send_key, kicad_click, kicad_window_info, kicad_screenshot_all, close KiCad, kicad versions, kicad_list_versions, KiCad bridge."

adom-desktop — KiCad bridge

All commands dispatch to the KiCad Python bridge running alongside the desktop app. Invoke from this container via Bash:

adom-desktop kicad_<action> '<json_args>'

The leading kicad_ routes the call to the KiCad plugin; the <action> names below are the plugin-side command names.

FIRST-TIME / COLD-START — read before you panic

A fresh machine can be missing KiCad, or the reverse-bridge plugin auto-installs on your first call. These states are EXPECTED — don't declare defeat. Branch on the stable errorCode (not the prose), and relay the returned _hint to the user verbatim.

Signal (errorCode / field) What it means What YOU do
host_app_not_installed (generic; hostApp:"KiCad". Legacy alias kicad_not_installed in errorCodeLegacy) KiCad (the user's host app) isn't on this machine. AD detects host apps but never auto-installs them. Don't send the user to download it. Offer to install it, then run kicad_upgrade '{}' — the agent installs the official build from scratch. Then retry.
kicad_version_not_installed The kicadVersion you asked for isn't installed. Run kicad_list_versions '{}'; retry with an installed version or omit kicadVersion to use the newest.
pluginAutoInstall present in a response Your first kicad_* call auto-installed the reverse-bridge plugin into KiCad (idempotent). Nothing — expected. Subsequent calls are near-zero cost.
bridge not responding on the first call AD is lazy-spawning the bridge (+ ~9s KiCad detection). Wait a beat and retry; it binds once and stays up.

Readiness before you drive:

  • kicad_readiness '{}' — read-only, zero side effects: is KiCad installed/ready? ({detected, ready, versionCount, defaultVersion}.) There's no prewarm — KiCad is a host app you install on request via kicad_upgrade, not a downloaded runtime asset.
  • kicad_describe '{}' — the full machine-readable verb catalog (the completeness escape hatch; the per-call _hints are what carry you in practice).
  • For "what EDA tools do I have" across all bridges, use AD's bridge_readiness (see below).

Installing KiCad on a fresh machine (hard-won, v0.9.26+)

kicad_upgrade downloads the official downloads.kicad.org installer and silent-installs it. Two things that WILL bite on a truly fresh machine, both handled for you now:

  • Install scope is mandatory in silent mode. KiCad 10's installer is NsisMultiUser: bare /S exits instantly with rc=666660 ("invalid command-line parameters") and installs nothing. The bridge auto-picks the scope: /allusers when the AD process is elevated (installs to Program Files), else /currentuser (installs to %LOCALAPPDATA%\Programs\KiCadno admin, no UAC prompt at all). Force it with kicad_upgrade '{"scope":"user"}' — that's your answer to "install KiCad without a UAC prompt." (Elevation note: on a VM/kiosk the AD process may already be elevated even though nobody clicked UAC — an elevated installer that launches the app hands down its admin token. kicad_upgrade '{"diagnoseOnly":true}' reports the real token/UAC facts.)
  • Library installs work before KiCad's first launch. %APPDATA%/kicad/<ver>/ (the per-user lib tables) doesn't exist until KiCad's first GUI run, so kicad_install_library/_footprint used to fail "config directory not found." The bridge now bootstraps that config (seeding the lib tables from the install template) automatically — installs just work on a never-launched KiCad.

GPU-less hosts (VM/RDP/server): KiCad pops a blocking "Could not use OpenGL" dialog and the heavy editors may not render. The bridge auto-expires that dialog and switches KiCad to the Cairo software canvas — see kicad-interaction for the dialog/canvas details.

Multi-version (KiCad 9 + KiCad 10 side-by-side)

Users can have multiple KiCad versions installed at the same time. The bridge auto-discovers everything under C:/Program Files/KiCad/<version>/ and defaults to the newest installed version if you don't specify one.

# Discover what's installed (run this first if unsure)
adom-desktop kicad_list_versions '{}'
# → {"versions":[{"version":"10.0", "default":true, ...}, {"version":"9.0", ...}], "default":"10.0", "count":2}

Every kicad_open_* (and install_*, run_drc) command accepts an optional kicadVersion arg to pin a specific install:

# Open in KiCad 10 (newest — default if you omit kicadVersion)
adom-desktop kicad_open_board '{"filePath":"C:/designs/foo.kicad_pcb"}'

# Open in KiCad 9 explicitly (e.g. to check that an older project still works)
adom-desktop kicad_open_board '{"filePath":"C:/designs/foo.kicad_pcb","kicadVersion":"9.0"}'

If you pass a version that's not installed, the bridge returns a hint listing the installed versions. The success response includes kicadVersionUsed so you can confirm which install actually ran.

Note on libraries / config: each KiCad version has its own sym-lib-table and fp-lib-table (in %APPDATA%/kicad/<version>/). kicad_install_library writes to the table of whichever version was selected — so if the user installs a library and then asks "open it in KiCad 9", you may need to install it under both versions.

"What EDA tools do I have?" — readiness & host-app detection

KiCad is the user's HOST APP. Adom Desktop detects it — it won't silently auto-install it as a prewarm/dependency (AD v1.9.47+). But if KiCad isn't found, do NOT hand the user a manual download — offer to install it for them and run kicad_upgrade '{}'. That verb installs the latest stable from the official downloads.kicad.org installer (silent /S, Windows only; may raise a UAC prompt) and installs from scratch, not just upgrades. The distinction: AD-core never auto-installs a host app, but a user-requested, agent-run install is exactly right.

  • To answer "what EDA tools / host apps do I have?" across every bridge, call the AD-level verb adom-desktop bridge_readiness '{}' — AD aggregates each bridge's host-app detection (KiCad, Fusion 360, …) into one report. Start here for any "do I have X installed?" question.
  • For KiCad specifically, adom-desktop kicad_readiness '{}' is a zero-side-effect read-only probe: {hostApp, detected, ready, versionCount, defaultVersion, versions[]}. It does not install the plugin or spawn subprocesses, and works even when KiCad is absent (detected:false). Use kicad_list_versions when you need the full per-version detail (paths, IPC API, lib tables).

Commands

CLI form Action Purpose Key args
kicad_list_versions list_versions Enumerate every installed KiCad version with paths and which one is the default
kicad_readiness readiness Read-only host-app detection: is KiCad installed/ready? Zero side effects (no plugin load, no subprocess); works even when KiCad is absent. For cross-bridge "what do I have", use AD's bridge_readiness
kicad_check_for_updates check_for_updates Read-only: installed KiCad vs latest STABLE (from downloads.kicad.org / KiCad GitLab tags); flags when the install predates the modern IPC/kipy automation API and should be upgraded
kicad_upgrade upgrade Download the official KiCad installer from downloads.kicad.org and silent-install it (/S) — not winget (winget lags the real release). May raise a UAC prompt to approve optional version, force
kicad_open_schematic open_schematic Open a .kicad_sch in the Schematic Editor filePath, optional kicadVersion
kicad_open_board open_board Open a .kicad_pcb in the PCB Editor filePath, optional kicadVersion
kicad_open_symbol_editor open_symbol_editor Launch Symbol Editor (optional: open specific library/symbol) libraryName, symbolName, optional kicadVersion
kicad_open_footprint_editor open_footprint_editor Launch Footprint Editor libraryName, footprintName, optional kicadVersion
kicad_open_3d_viewer open_3d_viewer Show the board (or footprint) in 3D viewer editor ("auto"/"pcb"/"fp" — "auto" prefers the board when both editors are open, no need to close sub-editors), optional kicadVersion
kicad_close_symbol_editor close_symbol_editor Close Symbol Editor
kicad_close_footprint_editor close_footprint_editor Close Footprint Editor
kicad_close_3d_viewer close_3d_viewer Close 3D viewer
kicad_close close Close KiCad (all editors)
kicad_window_info window_info Enumerate open KiCad windows (HWND, title, bounds, editor type)
kicad_install_library install_library Register a .kicad_sym + .pretty/ pair in sym-lib-table + fp-lib-table libraryPath, libraryType, libraryName, optional kicadVersion
kicad_install_symbol install_symbol Add a single symbol to an existing library fileName, fileContent, optional kicadVersion
kicad_install_footprint install_footprint Add a single footprint to an existing library library, footprint_path, optional kicadVersion
kicad_run_drc run_drc Run DRC on the current board, return violations filePath, optional kicadVersion
kicad_fix_keyboard fix_keyboard Workaround stuck-modifier bug after screen lock
kicad_screenshot_all screenshot_all Capture every open KiCad window (lossless PNGs)
kicad_send_key send_key Single key to an EXACT hwnd (e.g. Enter/Escape to a dialog). For modifier CHORDS ("ctrl+s", "alt+3") use AD's desktop_press_key — don't route chords here. hwnd, key
kicad_click click Send a click at (x, y) in a KiCad window hwnd, x, y
kicad_adom_library_status adom_library_status Report whether the Adom shared library is registered

Quick examples

# Open a schematic
adom-desktop kicad_open_schematic '{"path":"C:/designs/foo.kicad_sch"}'

# List open KiCad windows
adom-desktop kicad_window_info '{}'

# Screenshot every KiCad window
adom-desktop kicad_screenshot_all '{}'

# Run DRC
adom-desktop kicad_run_drc '{"board_path":"C:/designs/foo.kicad_pcb"}'

# Install a library pair
adom-desktop kicad_install_library '{
  "name":"my-lib",
  "sym_path":"C:/libs/my-lib.kicad_sym",
  "fp_path":"C:/libs/my-lib.pretty"
}'

Error shape

Every failing response includes a _hint field with a human-readable next step — surface it to the user verbatim when a KiCad command fails.

Bridge architecture (v1.8.31+) — you don't need to know any port

Earlier versions of the KiCad bridge listened on hardcoded port 8772. As of v1.8.31, bridges use OS-assigned ephemeral ports — every spawn gets a new free port. You never need to know it.

  • The CLI (adom-desktop kicad_*) automatically routes through adom-desktop's direct API (default port 47200 as of v1.8.33, with auto-fallback to 47201-47209 if 47200 is taken). adom-desktop then forwards to the bridge's actual runtime port.
  • The bridge port is internal plumbing and can change every spawn. bridge_list reports it as spawn.runtimePort for debugging only — do NOT hardcode that anywhere.
  • Why: this lets adom-desktop coexist with Hydrogen Desktop (which used to claim 8772 itself) and any other tool that grabs ports in the 8000 range. Side-by-side bridges from different apps no longer collide.
  • The relay path (Docker → wss proxy → Windows GUI) is unchanged — same adom-desktop kicad_* verbs, same JSON shape.

If you ever find yourself wanting to talk directly to the KiCad bridge process: don't. Go through the verb dispatch. If the verb you need doesn't exist, request a feature in adom-inc/adom-desktop.

  • adom-desktop-discovery (gallia) — ensures the CLI + relay are installed.
  • adom-desktop-fusion — sibling bridge for Fusion 360.
  • adom-desktop-direct-api — the direct API contract (port 47200 + 47201-47209 fallback, discovery file at ~/.adom/direct-api-port).
  • Repo: adom-inc/adom-desktop/plugins/kicad/