# Adom Desktop — KiCad Bridge

A **reverse bridge** that lets Adom Desktop (AD) — and the AI driving it — control the user's own
KiCad on Windows: open and drive every editor, install symbol/footprint libraries, place parts, run
DRC/ERC, export manufacturing files, and screenshot any window back to the AI.

KiCad is the user's **host app**. The bridge *detects* an existing KiCad and, if none is present,
*installs* one for them — it never asks the user to download or click through anything by hand.

- **Page / docs:** https://wiki.adom.inc/adom/adom-desktop-kicad-bridge
- **Bridge SDK:** https://wiki.adom.inc/adom/adom-desktop-bridges
- **Verb namespace:** `kicad_*` &nbsp;·&nbsp; **Status verb:** `kicad_bridge_status` &nbsp;·&nbsp; **Health:** `GET /status`

> Every screenshot in this README was captured on **ADOMBASELINE**, a stock Hyper-V VM with **no
> GPU**, driven end-to-end through the bridge — install → libraries → editors → 2D → 3D. If it
> renders there, it renders on a real laptop.

---

## Demo — narrated live editor tour (real screen recording)

[![KiCad bridge live demo](https://wiki.adom.inc/blob/app/adom-desktop-kicad-bridge/kicad-bridge-demo-poster.png)](https://wiki.adom.inc/blob/app/adom-desktop-kicad-bridge/kicad-bridge-demo.mp4)

**▶ [Watch the demo](https://wiki.adom.inc/blob/app/adom-desktop-kicad-bridge/kicad-bridge-demo.mp4)** (48s, 🔊 narrated) — the bridge driving real KiCad on a Windows VM: **select** a footprint and **zoom** the copper in the PCB editor, **rotate** the assembled board in 3D, then tour the schematic, symbol, and footprint editors. Genuine screen recording of the live windows (zoom / select / 3D rotation), narrated section by section — not animated stills.


---

## The demo verb — `kicad_demo`

One verb that shows the whole bridge off, built for the AI that demos Adom Desktop
during Hydrogen Desktop's install. Six beats, in the order a hardware person thinks:

| Beat | Shows |
|---|---|
| 1 | the **schematic symbol** in the user's own Symbol Editor |
| 2 | the **footprint** for that same part |
| 3 | that part in **3D** |
| 4 | a **schematic** using it (U1 + two 10k resistors) |
| 5 | the **2D board layout** |
| 6 | the finished **board in 3D** |

```bash
adom-desktop kicad_demo '{}'                      # start: prepares, warms KiCad, opens beat 1
adom-desktop kicad_demo '{"step":"footprint"}'    # ...then follow data.nextCall each time
adom-desktop kicad_demo '{"all":true}'            # bulk (non-interactive; slower than one request budget)
adom-desktop kicad_close '{"force":true}'         # tear down
```

**It narrates itself.** Every beat returns `say` (a line to speak), `pointOut`
(what's actually on screen), `window` (match it in `kicad_screenshot_all`) and
`nextCall`. One beat per call is the default precisely so the AI can talk, screenshot,
then move on.

**It ships nothing.** The two demo parts, the schematic and the board are all
generated in code, and the 3D bodies come from KiCad's *own* bundled
`3dmodels/*.3dshapes` — so the runtime zip stays small and the 3D views are real.
Parts install into the user's real `Adom` library; the project lands in
`Documents/adom-kicad-demo`.

**No KiCad? It offers to install it.** `kicad_demo` returns an offer instead of an
error; `kicad_demo '{"installKiCad": true}'` silently installs the official build
(per-user, no UAC) and then runs the tour. Watching the AI install your EDA tool is
itself a good demo beat.

**It never takes your screen.** Every window opens in the background and all input is
window-targeted (UIA / `PostMessage`), so you can keep working while it runs.

---

## How it fits together

The bridge is a `spawn.kind: python` process AD launches on the user's machine (`entrypoint:
server.py`, `port: 0` — AD picks the port and passes `ADOM_BIND_HOST`). It speaks HTTP
(`POST /command`, `GET /status`) and reaches KiCad through **four control surfaces**, picking the
lightest one that can do the job.

![Control surfaces](https://wiki.adom.inc/blob/app/adom-desktop-kicad-bridge/control-surfaces.svg)

| # | Surface | Used for | Where |
|---|---------|----------|-------|
| 1 | **kicad-cli** (subprocess) | headless DRC/ERC, gerber/pdf/svg/step/bom export, format upgrade | `handlers/export.py`, `run_drc`, `run_erc`, `lint_*` |
| 2 | **KiCad IPC (kipy)** | board/schematic introspection, confirmed footprint placement (KiCad 9+) | `handlers/place_footprint.py` |
| 3 | **Embedded Python** | JSON-RPC *inside* each KiCad process, dispatched on its wx UI thread | `plugin_payload/adom_bridge.py`, `handlers/bridge_client.py` |
| 4 | **Win32 / UIA / SendKeys** | open editors, screenshots, clicks/keys, dialog handling, window management | `handlers/kicad_ui.py`, `handlers/close_windows.py` |

---

## The window tour

Everything below was opened and captured on the GPU-less VM. Sample data is the **RP2040 breakout**
generated by `tour-pack-rp2040/` (an `AdomRP2040` symbol + `QFN-56_AdomRP2040` footprint + a board).

### Schematic editor — `kicad_open_schematic`

The RP2040 breakout: the MCU (U1), USB-C, a 12 MHz crystal, decoupling, and mounting pins.

![Schematic editor](https://wiki.adom.inc/blob/app/adom-desktop-kicad-bridge/schematic-editor.png)

### Symbol editor — `kicad_open_symbol_editor`

Opens straight to a symbol (`kicad_install_symbol` puts it in a user library first).

![Symbol editor](https://wiki.adom.inc/blob/app/adom-desktop-kicad-bridge/symbol-editor.png)

### Footprint editor — `kicad_open_footprint_editor`

`{"footprintName":"QFN-56_AdomRP2040","library":"AdomRP2040"}` loads the part directly — 56 pins +
thermal pad, 7×7 mm, 0.4 mm pitch, courtyard and silkscreen.

![Footprint editor](https://wiki.adom.inc/blob/app/adom-desktop-kicad-bridge/footprint-editor.png)

### PCB editor (2D) — `kicad_open_board`

The routed breakout — copper, silkscreen, the QFN-56 land pattern, mounting holes.

![PCB editor 2D](https://wiki.adom.inc/blob/app/adom-desktop-kicad-bridge/pcb-editor-2d.png)

### 3D viewer — `kicad_open_3d_viewer {"editor":"pcb"}`

The full board in 3D — board body, the USB-C connector's 3D model, the QFN chip body, SMD parts,
plated through-holes. **Rendered on the CPU via the software-OpenGL fallback (below); reload 1.7 s.**

![3D viewer](https://wiki.adom.inc/blob/app/adom-desktop-kicad-bridge/3d-viewer.png)

---

## Install & upgrade — zero manual steps

The bridge never tells the user to go download KiCad. `kicad_upgrade` fetches the official installer
and runs it silently, picking the scope automatically:

- **Elevated AD** → `/allusers /S` (system-wide, `%ProgramFiles%\KiCad`).
- **Non-elevated AD** → `/currentuser /S` (`%LocalAppData%\Programs\KiCad`, **no UAC prompt**).

`kicad_readiness` reports whether KiCad is installed and ready without side effects; the AI routes on
it before offering to install. Hard-won install details (all handled for you):

- KiCad 10's NsisMultiUser installer **requires** a scope flag — bare `/S` errors `rc=666660`.
- AD's portable Python has **no CA bundle**; the bridge ships `certs/cacert.pem` and uses it for TLS.
- Downloads are size-checked against `Content-Length` (a truncated installer otherwise fails at NSIS).
- `%APPDATA%/kicad/<ver>/` lib tables don't exist until first launch — the bridge **bootstraps** them
  so `install_library`/`install_footprint` work on a never-opened KiCad.
- `kicad_upgrade {"diagnoseOnly":true}` reports token-elevation type + `EnableLUA` without installing.

---

## Dialogs & error handling — the bridge clears the pointless ones

KiCad throws modal dialogs that stall automation. The bridge **scans every window owned by a running
KiCad process** (by PID — reliable, unlike title matching), auto-expires the benign ones, screenshots
what it dismissed, and returns a hint so the AI can decide what (if anything) to tell the user.

Auto-expired benign dialogs include:

- **"Could not use OpenGL / falling back to software rendering"** (GPU-less hosts).
- **"Welcome to KiCad — starting for the first time"** first-run wizard (dismissing accepts defaults).
- **"This file was created by an older version of KiCad"** conversion notice.

![First-run wizard, auto-dismissed](https://wiki.adom.inc/blob/app/adom-desktop-kicad-bridge/dialog-firstrun-wizard.png)

Verbs:

- `kicad_window_info` — lists windows and **self-heals** (auto-expires benign dialogs) by default.
- `kicad_dismiss_dialogs {"all":true}` — clear everything blocking; `{"screenshot":true}` returns
  images of each; `{"forceSoftwareCanvas":true}` persists Cairo canvas; `{"debug":true}` dumps the
  raw PID-based scan.
- `kicad_screenshot_all` — one call returns **every** open KiCad window, so the AI can spot an error
  dialog it didn't expect and read the message.

---

## Software-OpenGL fallback (last resort)

`kicad_enable_software_opengl` deploys Mesa's `llvmpipe` (a CPU OpenGL rasterizer) into KiCad's `bin`
so a box with **no usable GPU** — Hyper-V, RDP, headless CI — can still render the editors and the 3D
viewer. This is how every 3D shot above exists.

> ⚠️ It renders on the CPU and is **slow**. It is a worst-case fallback only — a real GPU (or GPU-P /
> DDA passthrough) is vastly better. The bridge keeps it so a GPU-less box isn't a dead end; it is
> never suggested proactively.

---

## Verb reference

All 41 verbs (prefix `kicad_`). Call `kicad_describe` for the live catalog with per-verb hints,
related verbs, and pitfalls.

**Windows & UI** — `open_board`, `open_schematic`, `open_symbol_editor`, `open_footprint_editor`,
`open_3d_viewer`, `open_editors`, `close_symbol_editor`, `close_footprint_editor`, `close_3d_viewer`,
`close`, `window_info`, `dismiss_dialogs`, `screenshot_all`, `send_key`, `click`, `fix_keyboard`

**Libraries & parts** — `install_library`, `install_symbol`, `install_footprint`, `install_plugin`,
`place_footprint`, `adom_library_status`

**Checks & export** — `run_drc`, `run_erc`, `lint_board`, `lint_schematic`, `lint_library`,
`format_upgrade`, `export_gerber`, `export_pdf`, `export_svg`, `export_step`, `export_bom_csv`

**Detect, install & meta** — `list_versions`, `readiness`, `describe`, `enable_software_opengl`,
`check_for_updates`, `upgrade`, `bridge_status`, `bridge_call`

---

## Running / dependencies

AD provisions everything; there is nothing to install by hand.

- **Python** ≥ 3.11 (AD provisions it) — stdlib only, plus the bundled `certs/cacert.pem`.
- **KiCad** ≥ 7.0 (host app; `kicad_upgrade` installs it if absent).
- **OS:** Windows (macOS/Linux detection stubs exist; the GUI surfaces are Windows-first).

The bridge binds `ADOM_BIND_HOST` on an AD-assigned port — never `0.0.0.0`. Auto-updates via
`updateManifestUrl` in `bridge.json`.

---

*Developer & publish notes live in `dev-skills/` and `publish-skills/` (source-only, never shipped to
a user install).*
