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.
master
| Name | Last updated |
|---|---|
| esc | 24d ago |
| evidence | 29d ago |
| ab-dev-pin-fix.patch | 1mo ago |
| make_fixture.py | 1mo ago |
| README.md | 1mo ago |
| run_demo.py | 1mo ago |
Live routing development demo
This branch adds explicit copper editing via the official KiCad IPC API. The AI or caller chooses the route; this is not a general obstacle-avoiding autorouter. The six-net fixture exercises 13 pads, a branched net and two layer changes.
The Astra promotion shows a condensed KiCad placement/routing sequence, but does not document its routing API. This demo implements the visible copper-editing portion ourselves.
Container checks
python3 -m pip install --target /tmp/kicad-routing-deps -r requirements-routing.txt
PYTHONPATH=/tmp/kicad-routing-deps python3 -m unittest discover -s tests -v
python3 tools/build_routing_dev.py /tmp/kicad-routing-overlay.zip
python3 demo/routing/make_fixture.py /tmp/kicad-routing-fixture
Installation
From bridge 0.9.340 the routing verbs and their IPC client (routing_deps/, Windows wheels for
CPython 3.11, 3.12 and 3.13) ship inside the normal release zip; nothing is pip-installed on the
desktop. Install the release the canonical way (bridge_install with the tier manifest), then:
- Save existing work and
kicad_closefirst: a running KiCad rewrites its preferences on exit and would undo the switch. kicad_ipc_api {"enable":true}writes KiCad'sapi.enable_serverswitch (backup kept).- Open the fixture board so KiCad starts with the IPC server on.
kicad_routing_state {"filePath":...}must return arevisionbefore any mutation.
The overlay tools (tools/build_routing_dev.py, tools/install_routing_dev.py) remain for
patching a dev-pinned cache during development; they are not the release path.
Open the generated PCB in KiCad 10.0.1+ with its IPC API enabled. Do not regenerate or overwrite it while open. Use a separate config for a shared test machine.
ADOM_API=https://RELAY/proxy/8766 python3 demo/routing/run_demo.py \
--target arav-rog --board 'C:/Users/arav/Documents/adom-routing-dev/live-routing.kicad_pcb' \
--plan /tmp/kicad-routing-fixture/plan.json --per-trace --output /tmp/routing-evidence
Omit --per-trace to commit one whole net per call. The script refuses preexisting
copper, records responses, and requires zero remaining nets, zero DRC errors and
zero unconnected items. Warnings are reported separately. It leaves edits unsaved
unless --save is supplied. Each call is a native Undo step. The board need not
be foregrounded for IPC edits; visual evidence requires a window capture.
Acceptance for a release: run both modes on a test box, verify vias/branches and native Undo, and exercise wrong-net/stale-revision/clearance rejection (see the verified results below).
The companion ab source patch targeted ab 2.1.38 and is historical: ab 2.1.70 ships the explicit-install guard upstream (adom-bridge#159), verified on arav-rog 2026-09-07 with ab 2.1.71: bridge_install while dev-pinned returns errorCode dev_pinned.
All routing and recording run in the background. For UI verification, inspect
desktop_ui_tree and invoke desktop_ui_click; use exact Win32 menu commands
for Undo (Ctrl+Z) and Redo (Ctrl+Y). Do not use Ctrl+Shift+Z in KiCad (it
activates Draw Filled Zones), or foreground the editor to dismiss a dialog.
Verified result (2026-09-05)
Both modes passed on AdomLapper with KiCad 10.0.5: six connected nets, 13 pads, 20 segments and two through vias; zero DRC errors and zero unconnected items. Three warnings identify the deliberately uninstalled RoutingFixture library. Wrong-net, stale-revision and crossing-route rejection, dry-run immutability, native Undo/Redo, removal, and Undo restoring all 22 removed items passed.
The final per-trace recording was captured in the background, finalized at 565 frames (1984x1250, 15fps, 37.67 seconds) and decoded without errors. In per-trace mode the full net is DRC-checked once before its exact segments/vias are committed against consecutive board revisions. Final DRC checks the complete live board. The final PCB was saved and pulled back for inspection. Structured results: evidence/AdomLapper-2026-09-05.json.
Pinned refresh returned pinned_dev; the live routing source hash was identical
before and after. Explicit bridge_install protection landed upstream in ab 2.1.70
(adom-bridge#159), so the companion patch is historical.
The companion ab patch passed cargo check --locked against 2.1.39 source and its four
pin-guard tests, but was never shipped; the upstream guard in ab 2.1.70 superseded it.
Verified result (2026-09-07, arav-rog, release 0.9.340)
Both modes passed on arav-rog with KiCad 10.0.3, ab 2.1.66, Python 3.12 and the vendored
routing_deps/cp312: six nets, 13 pads, 20 segments, two vias, zero DRC errors, zero unconnected
(three warnings for the fixture's uninstalled library). Wrong-net, stale-revision and crossing-route
rejection, dry-run immutability, removal of all 22 items and native Undo/Redo passed. Evidence:
evidence/arav-rog-2026-09-07.json.
Snapshot validation limits
Validation (0.9.341 and later) refills zones on the disposable snapshot, so the live board and the
source file are never touched; the report carries zonesRefilled:true. Project and custom rule files
are copied alongside the snapshot. If an unconnected list may be capped, its count is labelled a lower
bound (unconnectedCountIsLowerBound). If a violation list may be capped, route validation refuses the
before/after comparison with drc_incomplete before changing any copper. None of this is electrical
sign-off.