app
KiCad - the KiCad Bridge
Public Made by Adomby adom
Drive your own KiCad from an AI, in the background: open every editor, read the whole board as data (the EDA Bridge Standard board model), stack-up, part heights, netlists, place, route, pour, DRC and exports.
master
John Lauer
0.9.340: routing tests, demo runner + evidence (arav-rog 2026-09-07), vendoring and overlay tools, release notes
25dcdaf
2mo ago
"""Rebuild routing_deps/ (the vendored IPC client for the live routing verbs).
Downloads Windows x64 wheels for requirements-routing.txt, one tree per CPython
ABI the bridge may run under (start.bat picks system Python, else KiCad's), and
unpacks them under routing_deps/cp<maj><min>. The tree ships in the release zip
(tools/release_files.json "dirs") and is deliberately not pushed to the page repo.
python3 tools/vendor_routing_deps.py # cp311 cp312 cp313
python3 tools/vendor_routing_deps.py 3.12 # one ABI
"""
import shutil
import subprocess
import sys
import tempfile
import zipfile
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
OUT = ROOT / "routing_deps"
README = """Vendored Python dependencies for the live routing verbs (requirements-routing.txt),
unpacked from Windows x64 wheels, one tree per CPython ABI: cp311, cp312, cp313.
handlers/live_routing.py appends routing_deps/cp<major><minor> to sys.path when it exists.
Other platforms: pip install -r requirements-routing.txt into the bridge's Python.
Rebuild with tools/vendor_routing_deps.py; never edit by hand.
"""
def main():
versions = sys.argv[1:] or ["3.11", "3.12", "3.13"]
if OUT.exists():
shutil.rmtree(OUT)
OUT.mkdir()
(OUT / "README.txt").write_text(README)
for ver in versions:
tag = "cp" + ver.replace(".", "")
target = OUT / tag
target.mkdir()
with tempfile.TemporaryDirectory() as tmp:
subprocess.run([sys.executable, "-m", "pip", "download", "-r", str(ROOT / "requirements-routing.txt"),
"--platform", "win_amd64", "--python-version", ver, "--implementation", "cp",
"--only-binary=:all:", "-d", tmp, "-q"], check=True)
wheels = sorted(Path(tmp).glob("*.whl"))
for wheel in wheels:
with zipfile.ZipFile(wheel) as z:
z.extractall(target)
print(f"{tag}: {len(wheels)} wheels -> {target}")
print("done:", OUT)
if __name__ == "__main__":
main()