---
name: kicad-interaction
description: Foundational rules for interacting with KiCad on the user's desktop via adom-desktop. Read BEFORE any kicad_open_board, kicad_open_3d_viewer, kicad_send_key, or kicad_screenshot_all call. Covers state checks, window management, dialog handling, file updates, and the 3D viewer workflow. Trigger words — open in kicad, kicad desktop, send to kicad, kicad 3d viewer, kicad screenshot, kicad dialog, kicad file warning, open board in kicad, kicad pcb editor.
---

# kicad-interaction

Read this skill BEFORE any KiCad desktop operation. It prevents the most common mistakes: duplicate windows, unhandled dialogs, and blind file pushes.

## Dialogs: the bridge auto-expires the pointless ones, and tells you what it closed (v0.9.29+)

KiCad throws blocking modal dialogs constantly (OpenGL fallback notices, "older file format" warnings, save prompts, config nags). A blocking dialog **stalls every other verb** — an editor open can't complete, a screenshot captures only the dialog. The bridge now handles this **programmatically** so you rarely babysit it:

- **`kicad_window_info` auto-expires *benign* dialogs by default.** It scans EVERY window owned by any running KiCad process (matched by PID — reliable, never misses one), clicks OK on the harmless ones (e.g. *"Could not use OpenGL, falling back to software rendering"*, the *"Welcome to KiCad — starting for the first time"* first-run wizard, and the *"created by an older version of KiCad"* conversion notice), and reports them in `data.autoDismissed[]` + `data._autoDismissHint`. Pass `{"autoDismiss": false}` to inspect without touching them.
- **A NON-benign dialog is left up and reported** in `data.modalDialogs[]` with its `body` text (read from the dialog's Static controls — no screenshot needed) so YOU decide: read `body`, then dismiss with `kicad_send_key {hwnd, key:"return"}` (OK) / `"escape"` (Cancel), or surface it to the user.
- **`kicad_dismiss_dialogs`** — force-clear on demand. `{}` = benign only; `{"all": true}` = clear EVERY KiCad dialog (use after you've read a modal you want gone). It **screenshots each dialog before expiring it** (returned in `dismissed[].screenshot`) so you can show the user what was auto-closed and let them decide what it meant. Returns `dismissed[]`, `remaining[]`, hints.

**GPU-less hosts (VMs / RDP / servers):** KiCad tries OpenGL, fails, and pcbnew/3D may not render. When the bridge expires the OpenGL notice it also persists `graphics.canvas_type=2` (Cairo software) to `kicad_common.json` so future launches skip OpenGL — or force it up front with `kicad_dismiss_dialogs {"forceSoftwareCanvas": true}` then reopen the editor. (Note: a truly headless VM with no usable graphics stack may still not render the heavy editors or the 3D viewer even in Cairo. Last resort only: `kicad_enable_software_opengl` deploys Mesa `llvmpipe` (CPU OpenGL) so even 3D renders — it's SLOW and for GPU-less hosts only; do NOT suggest it proactively on a normal machine.)

**Pattern:** `open_* → window_info (auto-clears benign) → screenshot_all`. If an open "fails," a benign modal was almost certainly blocking it — call `window_info` or `kicad_dismiss_dialogs` and retry.

## Rule 1 — Always check state first

Before ANY KiCad operation, run:

```bash
adom-desktop kicad_window_info '{}'
```

This returns all open editors, 3D viewers, and modal dialogs with their hwnds. Parse the response and decide your next action based on what's already running.

**If the board is already open and you're pushing an updated file:**
```bash
adom-desktop kicad_close '{}'        # close everything
sleep 2
adom-desktop kicad_open_board '{"filePath":"C:/Users/john/Downloads/board.kicad_pcb"}'
```

**If the board is already open and you just need the 3D viewer:**
```bash
# Reuse the existing editor — get its hwnd from window_info
adom-desktop kicad_open_3d_viewer '{"hwnd": <existing_pcb_editor_hwnd>}'
```

**If KiCad is not running:**
```bash
adom-desktop kicad_open_board '{"filePath":"C:/Users/john/Downloads/board.kicad_pcb"}'
```

Never call `kicad_open_board` without checking `kicad_window_info` first.

## Rule 2 — Never open duplicate instances

Opening the same `.kicad_pcb` file twice triggers a "File Open Warning" dialog about interleaved saves. This is always wrong. The correct pattern when updating a file:

1. `kicad_window_info` — see what's open
2. `kicad_close` — close everything
3. `send_files` — push the updated file
4. `kicad_open_board` — open fresh

Do NOT open a second instance and then dismiss the warning. Close first, open once.

## Rule 3 — Always check for dialogs after operations

After `kicad_open_board`, `kicad_open_3d_viewer`, or any operation that might trigger a dialog:

```bash
sleep 3
adom-desktop kicad_window_info '{}'
```

Check `hasModalDialogs`. If true:
1. Screenshot the dialog: `desktop_screenshot_window '{"hwnd": <dialog_hwnd>}'`
2. Read the screenshot to understand the dialog
3. Dismiss with `kicad_send_key '{"key": "Enter", "hwnd": <dialog_hwnd>}'` or `"Escape"` as appropriate
4. Re-check `kicad_window_info` to confirm it cleared

## Rule 4 — File transfer before open

KiCad runs on Windows. The `.kicad_pcb` file lives on Docker. Always send first, then open:

```bash
# Send files (send large files like STEP/WRL separately to avoid 413)
adom-desktop send_files '{"filePaths":["/docker/path/board.kicad_pcb"],"category":"kicad"}'

# Files land in C:/Users/john/Downloads/ by default
adom-desktop kicad_open_board '{"filePath":"C:/Users/john/Downloads/board.kicad_pcb"}'
```

If you also have sidecar files (STEP/WRL models referenced with relative paths), send those too — they must land in the same directory as the PCB.

## Rule 5 — 3D viewer workflow

```bash
# 1. Check state
adom-desktop kicad_window_info '{}'

# 2. Open 3D viewer from the PCB editor (use hwnd from step 1)
adom-desktop kicad_open_3d_viewer '{"hwnd": <pcb_editor_hwnd>}'

# 3. Wait for render + confirm viewer appeared
sleep 5
adom-desktop kicad_window_info '{}'

# 4. Screenshot the 3D viewer window
adom-desktop desktop_screenshot_window '{"hwnd": <3d_viewer_hwnd>}'

# 5. Read the screenshot to verify models rendered
```

### Edge-mount connectors (USB-C, micro-USB, barrel jacks)

USB-C, micro-USB, barrel jacks, and other connectors that users plug cables into must overhang the board edge. After placing the footprint, verify in the 3D viewer that the connector mouth extends past the Edge.Cuts outline. If it doesn't, adjust the footprint Y position using the fab-layer board-edge alignment line.

**Verification workflow:**
1. Open the 3D viewer after placing an edge-mount connector
2. Screenshot and check that the connector body sticks out past the board edge
3. If it's flush or recessed, the user cannot plug in a cable -- adjust the footprint Y coordinate
4. The footprint's fab layer typically includes a line marking where the board edge should intersect the component

## Rule 6 — Available KiCad commands

```
kicad_open_board          Open a .kicad_pcb in the PCB Editor
kicad_open_3d_viewer      Open 3D viewer from a PCB Editor (needs hwnd)
kicad_close_3d_viewer     Close the 3D viewer
kicad_close               Close all KiCad windows
kicad_window_info         List all open editors, viewers, and dialogs
kicad_send_key            Single key to an EXACT hwnd (dialog Enter/Escape). For CHORDS use Bridge's desktop_press_key.
kicad_screenshot_all      Screenshot all KiCad windows
kicad_adom_library_status Check Adom library installation
kicad_install_symbol      Install a symbol to KiCad's library
kicad_install_footprint   Install a footprint to KiCad's library
kicad_install_library     Install a full library
kicad_run_drc             Run Design Rule Check
desktop_screenshot_window Screenshot a specific window by hwnd
desktop_bring_to_front    Focus a window by hwnd
```

## Rule 7 — Pup-over-webview preference for tool dashboards

User prefers tool dashboards (chip-fetcher, chiplinter, etc.) in **pup windows**, not Hydrogen webview tabs. The canonical pattern is two pup windows:

- **Dashboard pup window** (`sessionId: "chip-fetcher-dashboard"` or `"<tool>-dashboard"`) — the live status / card view. Never navigate this mid-batch.
- **Scrape / work pup window** (`sessionId: "chip-fetcher-scrape"` or `"<tool>-scrape"`) — where vendor pages, logins, and downloads happen.

Both windows MUST use the same `profile` (e.g. `profile: "chip-fetcher"`) so cookies and logins persist. Only the `sessionId` varies. This two-pup pattern keeps the user's view of progress (dashboard) completely isolated from the active scraping / interaction window.

## Rule 8 — Desktop connection prerequisite

Before any KiCad command, verify the desktop is connected:

```bash
adom-desktop ping
```

If disconnected, start the relay:
```bash
if ! curl -sf http://127.0.0.1:8766/health >/dev/null 2>&1; then
  nohup adom-desktop serve > /tmp/adom-desktop-relay.log 2>&1 &
  disown
  sleep 3
fi
adom-desktop ping
```
