← Commit history
README.md−2
@@ -46,8 +46,6 @@ How the dock card, the dashboard and this demo fit together: [docs/dashboard.md]  ## Live routing (from 0.9.340) -**[Codex Astra + KiCad: watch the routing progression and reproduce it](https://wiki.adom.inc/adom/kicad-bridge/files/docs/CODEX-ASTRA.md).** From six live nets to a four-layer BMS, with native routing films, multilayer comparisons and reusable engineering skills.- Four verbs edit copper in the open PCB editor through KiCad's official IPC API (KiCad 10.0.1+ with the IPC API server enabled): `kicad_routing_state`, `kicad_route_net`, `kicad_remove_route` and `kicad_routing_validate`. The AI chooses the waypoints; each call lands as one native Undo step,
dashboard/kicad_dashboard.py+5−1
@@ -1200,9 +1200,13 @@ def do_action(target, name, args):                 "_hint": "Launching in the background; the KiCad and Plugin LEDs show live "                          "progress and the page updates over /events as it happens."}     if name == "close":+        # Bridge 0.9.347: a plain close leaves an editor with unsaved work open and+        # answers errorCode unsaved_changes; the page asks the user before it+        # sends discard:true. force is never used from here (it kills silently).         set_activity("kicad", "closing the bridge's KiCad windows...", target)         try:-            return ab(target, "kicad_close", {"force": True}, timeout=180)+            payload = {"discardChanges": True} if args.get("discard") else {}+            return ab(target, "kicad_close", payload, timeout=180)         finally:             clear_activity("kicad", target)     if name == "demo":
dashboard/ui/index.html+1−1
@@ -610,7 +610,7 @@ async function refresh(force){ } $('#btnRefresh').onclick=()=>{toast('refreshing status');refresh(true);}; $('#btnLaunch').onclick=async()=>{toast('launching KiCad in the background - watch the KiCad LED');await act('launch');};-$('#btnClose').onclick=async()=>{toast('closing the bridge\u2019s KiCad windows');await act('close');setTimeout(()=>refresh(true),4000);};+$('#btnClose').onclick=async()=>{toast('closing the bridge\u2019s KiCad windows');let r=await act('close');if(r&&r.errorCode==='unsaved_changes'){const u=(r.unsavedChanges||[]).map(x=>x.window).join(', ');if(confirm('KiCad has unsaved changes in: '+u+'\n\nDiscard them and close?')){r=await act('close',{discard:true});}else{toast('left open: save in KiCad, then close again','warn');}}setTimeout(()=>refresh(true),4000);};  // Phrases come from dockbar.json `say` via the server, then the MODULE owns // everything else: card, grid, table, icons, clipboard, send, toasts, X and
install.sh

  
package.json+1−1
@@ -1,6 +1,6 @@ {   "slug": "kicad-bridge",-  "version": "1.0.133",+  "version": "1.0.134",   "type": "app",   "description": "Skills for your container so your AI knows how to drive the KiCad bridge. The bridge runtime itself is the release zip; Adom Bridge loads that.",   "tags": [
page.json+1−1
@@ -4,7 +4,7 @@   "slug": "kicad-bridge",   "title": "KiCad - the KiCad Bridge",   "brief": "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.",-  "version": "1.0.133",+  "version": "1.0.134",   "tags": [     "kicad",     "pcb",
uninstall.sh