app
KiCad - the 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.
← Commit history
README.md+180−180@@ -1,187 +1,187 @@-# Reference bridge: KiCad - +# Adom Desktop - KiCad Bridge+    -## Source code + contributing (2026-05) - -The KiCad bridge moved out of `adom-inc/adom-desktop`'s monorepo into its own dedicated repo so the community can extend it without coordinating with Adom Desktop's release cycle. - -### Where the source lives - -The canonical repo is **[`adom-inc/adom-bridge-kicad`](https://github.com/adom-inc/adom-bridge-kicad)** on GitHub. It's private today and will go public after a review pass. - -In the meantime, the full source — code, history, contributing guide, license — is **mirrored on this wiki page**: - -| Download | What it is | How to use | -|---|---|---| -| [`adom-bridge-kicad-source.tar.gz`](https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-desktop-kicad-bridge/adom-bridge-kicad-source.tar.gz) | Clean source tree, no `.git` directory. ~165 KB. | `tar xzf adom-bridge-kicad-source.tar.gz && cd adom-bridge-kicad/` | -| [`adom-bridge-kicad.bundle`](https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-desktop-kicad-bridge/adom-bridge-kicad.bundle) | Git bundle with full commit history. ~240 KB. | `git clone https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-desktop-kicad-bridge/adom-bridge-kicad.bundle adom-bridge-kicad && cd adom-bridge-kicad && git log` | - -No GitHub account needed to download either — both URLs are public. - -### How to contribute - -We accept community improvements. Most useful targets right now: - -- **KiCad 11 support** — when KiCad 11 ships, the `kicad_detect.py` discovery + the in-process bridge plugin both need updates. Fork-friendly. -- **macOS / Linux ports** — bridge currently Windows-only; cross-platform PRs welcome. -- **New verbs** — anything KiCad exposes via `pcbnew.*` / `kicad-cli` that you'd find useful. - -Two contribution paths, depending on your access: - -**With a GitHub account (preferred):** wait until we make the repo public, then fork on GitHub and open a PR. We're aiming to flip the repo public in the next maintenance pass. - -**Without GitHub access (patch-by-email-style, available right now):** Clone the bundle, make your changes, generate a patch with `git format-patch origin/main..HEAD --stdout > my-changes.patch`, and email it to **`[email protected]`**. Adom maintainers will review and apply. - -See `CONTRIBUTING.md` inside the tarball/bundle for the full PR + ship workflow. - -### How shipping works after merge - -1. Maintainer merges your PR into `main` -2. Maintainer tags `v<X.Y.Z>` + runs `bash scripts/release-bridge.sh kicad` on their box -3. New zip + manifest published to this wiki page (replaces current version) -4. Every Adom Desktop install running v1.7.19+ auto-picks up your change within 4 hours OR immediately via `adom-desktop refresh_bridges` - -No NSIS installer rebuild required. Your code reaches real users in ~30s after merge. - -### License - -MIT — see the `LICENSE` file in the tarball. - - - -The KiCad bridge is one of three reference implementations bundled with Adom Desktop. It's the most complex of the three — a multi-instance Python server that runs alongside KiCad GUI processes and provides both a forward path (CLI → bridge → kicad-cli) and a reverse path (CLI → bridge → in-process Python plugin inside KiCad). - -If you're authoring a new third-party bridge, see the [bridge SDK guide](https://wiki-ufypy5dpx93o.adom.cloud/wiki/apps/adom-desktop-bridges) first. Use this page for architectural reference once you've grasped the basics. - -## Quick facts - -| | | -|---|---| -| Name | `kicad` | -| Display | KiCad EDA | -| Spawn kind | Python (`server.py`) | -| Port | 8772 | -| Verb prefix | `kicad_*` (23 verbs) | -| Watcher | yes (`*.kicad_pcb`, `*.kicad_sch`, `*.kicad_pro`) | -| Source zip | [`kicad-bridge-v0.8.2.zip`](https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-desktop/kicad-bridge-v0.8.2.zip) | -| Manifest | [`kicad-bridge-manifest.json`](https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-desktop/kicad-bridge-manifest.json) | -| User-facing skill | [`kicad-SKILL.md`](https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-desktop/kicad-SKILL.md) | - -## What it does - -- **Forward path** (CLI → bridge → kicad-cli): board/schematic linting (`kicad_lint_board`, `kicad_lint_schematic`, `kicad_lint_library`), DRC/ERC (`kicad_run_drc`, `kicad_run_erc`), format upgrades, exports. -- **Window automation** (CLI → bridge → Win32): launch editors (`kicad_open_board`, `kicad_open_schematic`, …), list open editors, capture screenshots of all KiCad windows, send keystrokes, click at coords. -- **Reverse path** (CLI → bridge → in-process plugin inside KiCad): `kicad_bridge_call` invokes a Python handler running INSIDE the running KiCad GUI exe, with access to `pcbnew.*` / future `kipy`. This gives Docker-side Claude live introspection of the actually-open board without a round-trip through file exports. - -## `bridge.json` - -```json -{ - "manifest_version": 1, - "name": "kicad", - "displayName": "KiCad EDA", - "version": "0.8.2", - "description": "Reverse bridge for KiCad — board/schematic introspection, lint via kicad-cli, plugin install, multi-instance probe, in-process DRC.", - "homepage": "https://github.com/adom-inc/adom-desktop", - "author": "Adom Inc.", - "license": "MIT", - "spawn": { - "kind": "python", - "entrypoint": "server.py", - "port": 8772, - "healthEndpoint": "http://127.0.0.1:8772/status", - "stopMethod": "kill", - "killImageName": "python.exe" - }, - "verbPrefixes": ["kicad_"], - "verbs": [ - "kicad_open_board", "kicad_open_schematic", "kicad_open_symbol_editor", - "kicad_open_footprint_editor", "kicad_open_3d_viewer", - "kicad_list_versions", - "kicad_run_drc", "kicad_run_erc", - "kicad_lint_board", "kicad_lint_schematic", "kicad_lint_library", - "kicad_format_upgrade", - "kicad_install_plugin", "kicad_install_symbol", "kicad_install_footprint", - "kicad_bridge_status", "kicad_bridge_call", - "kicad_open_editors", "kicad_window_info", "kicad_screenshot_all", - "kicad_send_key", "kicad_click", "kicad_close" - ], - "dependencies": { "python": ">=3.11", "kicad": ">=10.0" }, - "category": "EDA", - "tags": ["pcb", "schematic", "open-source", "kicad-10", "kicad-11-ready"], - "watcher": { - "supports": true, - "displayName": "Project Watch", - "description": "Monitors a KiCad project folder for file changes and syncs them to Docker.", - "defaultGlobs": ["*.kicad_pcb", "*.kicad_sch", "*.kicad_pro"], - "configKey": "project_watch" - } -} -``` - -The `watcher` field declares that this bridge supports project-watching — the GUI renders a 👁 pip on the chip when watching is active. See the [bridge SDK guide](https://wiki-ufypy5dpx93o.adom.cloud/wiki/apps/adom-desktop-bridges#bridgejson-schema) for the full schema. - -## Architecture highlights - -``` -kicad/ -├── server.py ← HTTP entry point; routes /command to handlers/ -├── handlers/ ← One module per logical verb group -│ ├── board_ops.py ← kicad_run_drc, kicad_lint_board, kicad_open_board, … -│ ├── schematic_ops.py -│ ├── library_ops.py -│ ├── window_automation.py ← Win32 SendInput, PrintWindow, EnumWindows -│ ├── bridge_call.py ← Reverse bridge dispatch into the in-process plugin -│ └── … -├── kicad_detect.py ← Find installed KiCad versions, exe paths, USER_SITE -├── adom_library.py ← Symbol/footprint discovery in sym-lib-table.txt -├── lib_table.py ← Add/remove rows in *-lib-table files -├── plugin_install.py ← Copy adom_bridge.py into USER_SITE/usercustomize.py -├── plugin_payload/ -│ └── adom_bridge.py ← Reverse-bridge plugin loaded INSIDE every KiCad GUI exe -├── parsers/ ← .kicad_sym, .kicad_mod, .kicad_pcb tokenizers -└── start.bat ← Windows launcher for local dev -``` - -The reverse-bridge plugin (`plugin_payload/adom_bridge.py`) is what makes the kicad bridge special. KiCad's bundled Python interpreter overrides `site.USER_SITE` to `%USERPROFILE%\Documents\KiCad\10.0\3rdparty\Python311\site-packages\`, and the `usercustomize.py` import hook fires on every KiCad GUI exe start (`kicad.exe`, `pcbnew.exe`, `eeschema.exe`, `kicad-cli.exe`). Our plugin uses this hook to launch a tiny websocket client that connects to the bridge — turning every running KiCad into a remote-controllable instance. - -## Reverse-bridge example - -```bash -# From cloud Docker: list every open KiCad GUI exe + which board it has loaded -adom-desktop kicad_open_editors - -# Direct in-process call: ask the running pcbnew.exe what board it has open -adom-desktop kicad_bridge_call '{"method":"get_board_info"}' - -# Run a DRC IN-PROCESS — no file write, no kicad-cli detour -adom-desktop kicad_bridge_call '{"method":"run_drc","args":{"severity":"error"}}' -``` - -The bridge dispatches these to `adom_bridge.py` running inside pcbnew. The handler executes against the live `pcbnew.GetBoard()` and returns JSON over the websocket. - -## Reference: install the source locally to read - -```bash -# Pull the zip (no auth needed — wiki static URL) -curl -L https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-desktop/kicad-bridge-v0.8.2.zip -o /tmp/kicad-bridge.zip - -# Extract -mkdir -p /tmp/kicad-bridge && cd /tmp/kicad-bridge && python3 -c "import zipfile; zipfile.ZipFile('/tmp/kicad-bridge.zip').extractall()" -ls -la -``` - -You'll see `server.py`, `bridge.json`, `handlers/`, `plugin_payload/`, etc. — fork the layout for your own bridge. - -## Related - -- **[Bridge SDK guide](https://wiki-ufypy5dpx93o.adom.cloud/wiki/apps/adom-desktop-bridges)** — `bridge.json` schema, packaging recipe, lifecycle -- **[Puppeteer bridge reference](https://wiki-ufypy5dpx93o.adom.cloud/wiki/apps/adom-desktop-puppeteer-bridge)** — simpler architecture, single-instance, Node + Chrome for Testing -- **[Fusion 360 bridge reference](https://wiki-ufypy5dpx93o.adom.cloud/wiki/apps/adom-desktop-fusion-bridge)** — passthrough-to-add-in pattern +## Source code + contributing (2026-05)++The KiCad bridge moved out of `adom-inc/adom-desktop`'s monorepo into its own dedicated repo so the community can extend it without coordinating with Adom Desktop's release cycle.++### Where the source lives++The canonical repo is **[`adom-inc/adom-bridge-kicad`](https://github.com/adom-inc/adom-bridge-kicad)** on GitHub. It's private today and will go public after a review pass.++In the meantime, the full source — code, history, contributing guide, license — is **mirrored on this wiki page**:++| Download | What it is | How to use |+|---|---|---|+| [`adom-bridge-kicad-source.tar.gz`](https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-desktop-kicad-bridge/adom-bridge-kicad-source.tar.gz) | Clean source tree, no `.git` directory. ~165 KB. | `tar xzf adom-bridge-kicad-source.tar.gz && cd adom-bridge-kicad/` |+| [`adom-bridge-kicad.bundle`](https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-desktop-kicad-bridge/adom-bridge-kicad.bundle) | Git bundle with full commit history. ~240 KB. | `git clone https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-desktop-kicad-bridge/adom-bridge-kicad.bundle adom-bridge-kicad && cd adom-bridge-kicad && git log` |++No GitHub account needed to download either — both URLs are public.++### How to contribute++We accept community improvements. Most useful targets right now:++- **KiCad 11 support** — when KiCad 11 ships, the `kicad_detect.py` discovery + the in-process bridge plugin both need updates. Fork-friendly.+- **macOS / Linux ports** — bridge currently Windows-only; cross-platform PRs welcome.+- **New verbs** — anything KiCad exposes via `pcbnew.*` / `kicad-cli` that you'd find useful.++Two contribution paths, depending on your access:++**With a GitHub account (preferred):** wait until we make the repo public, then fork on GitHub and open a PR. We're aiming to flip the repo public in the next maintenance pass.++**Without GitHub access (patch-by-email-style, available right now):** Clone the bundle, make your changes, generate a patch with `git format-patch origin/main..HEAD --stdout > my-changes.patch`, and email it to **`[email protected]`**. Adom maintainers will review and apply.++See `CONTRIBUTING.md` inside the tarball/bundle for the full PR + ship workflow.++### How shipping works after merge++1. Maintainer merges your PR into `main`+2. Maintainer tags `v<X.Y.Z>` + runs `bash scripts/release-bridge.sh kicad` on their box+3. New zip + manifest published to this wiki page (replaces current version)+4. Every Adom Desktop install running v1.7.19+ auto-picks up your change within 4 hours OR immediately via `adom-desktop refresh_bridges`++No NSIS installer rebuild required. Your code reaches real users in ~30s after merge.++### License++MIT — see the `LICENSE` file in the tarball.++---+++The KiCad bridge is one of three reference implementations bundled with Adom Desktop. It's the most complex of the three — a multi-instance Python server that runs alongside KiCad GUI processes and provides both a forward path (CLI → bridge → kicad-cli) and a reverse path (CLI → bridge → in-process Python plugin inside KiCad).++If you're authoring a new third-party bridge, see the [bridge SDK guide](https://wiki-ufypy5dpx93o.adom.cloud/wiki/apps/adom-desktop-bridges) first. Use this page for architectural reference once you've grasped the basics.++## Quick facts++| | |+|---|---|+| Name | `kicad` |+| Display | KiCad EDA |+| Spawn kind | Python (`server.py`) |+| Port | 8772 |+| Verb prefix | `kicad_*` (23 verbs) |+| Watcher | yes (`*.kicad_pcb`, `*.kicad_sch`, `*.kicad_pro`) |+| Source zip | [`kicad-bridge-v0.8.2.zip`](https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-desktop/kicad-bridge-v0.8.2.zip) |+| Manifest | [`kicad-bridge-manifest.json`](https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-desktop/kicad-bridge-manifest.json) |+| User-facing skill | [`kicad-SKILL.md`](https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-desktop/kicad-SKILL.md) |++## What it does++- **Forward path** (CLI → bridge → kicad-cli): board/schematic linting (`kicad_lint_board`, `kicad_lint_schematic`, `kicad_lint_library`), DRC/ERC (`kicad_run_drc`, `kicad_run_erc`), format upgrades, exports.+- **Window automation** (CLI → bridge → Win32): launch editors (`kicad_open_board`, `kicad_open_schematic`, …), list open editors, capture screenshots of all KiCad windows, send keystrokes, click at coords.+- **Reverse path** (CLI → bridge → in-process plugin inside KiCad): `kicad_bridge_call` invokes a Python handler running INSIDE the running KiCad GUI exe, with access to `pcbnew.*` / future `kipy`. This gives Docker-side Claude live introspection of the actually-open board without a round-trip through file exports.++## `bridge.json`++```json+{+ "manifest_version": 1,+ "name": "kicad",+ "displayName": "KiCad EDA",+ "version": "0.8.2",+ "description": "Reverse bridge for KiCad — board/schematic introspection, lint via kicad-cli, plugin install, multi-instance probe, in-process DRC.",+ "homepage": "https://github.com/adom-inc/adom-desktop",+ "author": "Adom Inc.",+ "license": "MIT",+ "spawn": {+ "kind": "python",+ "entrypoint": "server.py",+ "port": 8772,+ "healthEndpoint": "http://127.0.0.1:8772/status",+ "stopMethod": "kill",+ "killImageName": "python.exe"+ },+ "verbPrefixes": ["kicad_"],+ "verbs": [+ "kicad_open_board", "kicad_open_schematic", "kicad_open_symbol_editor",+ "kicad_open_footprint_editor", "kicad_open_3d_viewer",+ "kicad_list_versions",+ "kicad_run_drc", "kicad_run_erc",+ "kicad_lint_board", "kicad_lint_schematic", "kicad_lint_library",+ "kicad_format_upgrade",+ "kicad_install_plugin", "kicad_install_symbol", "kicad_install_footprint",+ "kicad_bridge_status", "kicad_bridge_call",+ "kicad_open_editors", "kicad_window_info", "kicad_screenshot_all",+ "kicad_send_key", "kicad_click", "kicad_close"+ ],+ "dependencies": { "python": ">=3.11", "kicad": ">=10.0" },+ "category": "EDA",+ "tags": ["pcb", "schematic", "open-source", "kicad-10", "kicad-11-ready"],+ "watcher": {+ "supports": true,+ "displayName": "Project Watch",+ "description": "Monitors a KiCad project folder for file changes and syncs them to Docker.",+ "defaultGlobs": ["*.kicad_pcb", "*.kicad_sch", "*.kicad_pro"],+ "configKey": "project_watch"+ }+}+```++The `watcher` field declares that this bridge supports project-watching — the GUI renders a 👁 pip on the chip when watching is active. See the [bridge SDK guide](https://wiki-ufypy5dpx93o.adom.cloud/wiki/apps/adom-desktop-bridges#bridgejson-schema) for the full schema.++## Architecture highlights++```+kicad/+├── server.py ← HTTP entry point; routes /command to handlers/+├── handlers/ ← One module per logical verb group+│ ├── board_ops.py ← kicad_run_drc, kicad_lint_board, kicad_open_board, …+│ ├── schematic_ops.py+│ ├── library_ops.py+│ ├── window_automation.py ← Win32 SendInput, PrintWindow, EnumWindows+│ ├── bridge_call.py ← Reverse bridge dispatch into the in-process plugin+│ └── …+├── kicad_detect.py ← Find installed KiCad versions, exe paths, USER_SITE+├── adom_library.py ← Symbol/footprint discovery in sym-lib-table.txt+├── lib_table.py ← Add/remove rows in *-lib-table files+├── plugin_install.py ← Copy adom_bridge.py into USER_SITE/usercustomize.py+├── plugin_payload/+│ └── adom_bridge.py ← Reverse-bridge plugin loaded INSIDE every KiCad GUI exe+├── parsers/ ← .kicad_sym, .kicad_mod, .kicad_pcb tokenizers+└── start.bat ← Windows launcher for local dev+```++The reverse-bridge plugin (`plugin_payload/adom_bridge.py`) is what makes the kicad bridge special. KiCad's bundled Python interpreter overrides `site.USER_SITE` to `%USERPROFILE%\Documents\KiCad\10.0\3rdparty\Python311\site-packages\`, and the `usercustomize.py` import hook fires on every KiCad GUI exe start (`kicad.exe`, `pcbnew.exe`, `eeschema.exe`, `kicad-cli.exe`). Our plugin uses this hook to launch a tiny websocket client that connects to the bridge — turning every running KiCad into a remote-controllable instance.++## Reverse-bridge example++```bash+# From cloud Docker: list every open KiCad GUI exe + which board it has loaded+adom-desktop kicad_open_editors++# Direct in-process call: ask the running pcbnew.exe what board it has open+adom-desktop kicad_bridge_call '{"method":"get_board_info"}'++# Run a DRC IN-PROCESS — no file write, no kicad-cli detour+adom-desktop kicad_bridge_call '{"method":"run_drc","args":{"severity":"error"}}'+```++The bridge dispatches these to `adom_bridge.py` running inside pcbnew. The handler executes against the live `pcbnew.GetBoard()` and returns JSON over the websocket.++## Reference: install the source locally to read++```bash+# Pull the zip (no auth needed — wiki static URL)+curl -L https://wiki-ufypy5dpx93o.adom.cloud/static/apps/adom-desktop/kicad-bridge-v0.8.2.zip -o /tmp/kicad-bridge.zip++# Extract+mkdir -p /tmp/kicad-bridge && cd /tmp/kicad-bridge && python3 -c "import zipfile; zipfile.ZipFile('/tmp/kicad-bridge.zip').extractall()"+ls -la+```++You'll see `server.py`, `bridge.json`, `handlers/`, `plugin_payload/`, etc. — fork the layout for your own bridge.++## Related++- **[Bridge SDK guide](https://wiki-ufypy5dpx93o.adom.cloud/wiki/apps/adom-desktop-bridges)** — `bridge.json` schema, packaging recipe, lifecycle+- **[Puppeteer bridge reference](https://wiki-ufypy5dpx93o.adom.cloud/wiki/apps/adom-desktop-puppeteer-bridge)** — simpler architecture, single-instance, Node + Chrome for Testing+- **[Fusion 360 bridge reference](https://wiki-ufypy5dpx93o.adom.cloud/wiki/apps/adom-desktop-fusion-bridge)** — passthrough-to-add-in pattern - **[adom-desktop main page](https://wiki-ufypy5dpx93o.adom.cloud/wiki/apps/adom-desktop)** — install the parent app first