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.
kicad_show_library returns success:true when the symbol does not resolve - the editor keeps showing the PREVIOUS part (the #42 shape, on the symbol path)
kicad_show_library returns success: true when the requested symbol does not exist — the editor keeps showing the previous part, and nothing in the response says so.
The run
ConfRoomROG (Windows 11), kicad bridge 1.0.77, ab 2.0.79, over the galliaApril relay. Ten new wiki parts, .kicad_sym + .kicad_mod + .step staged from each part's wiki page, then kicad_install_symbol → kicad_install_footprint → kicad_show_library {libraryName, symbolName} per part, with a full-window capture of the Symbol Editor after each.
All ten pass once the caller works around the two problems below. The problems are what this issue is about.
Finding 1 — success with a stale editor
Part 4, CL21A226MPQNNNE:
kicad_show_library {"libraryName":"Adom","symbolName":"CL21A226MPQNNNE"}
→ {"success": true}
The symbol was never found. The editor was still showing part 3, 0603X475K100CT, and the capture looked completely healthy: correct-looking window, populated library tree, a real capacitor symbol drawn on the canvas. Ink coverage 40.9% — indistinguishable from the genuine passes, which ran 39.7–42.6%.
Only the window title gave it away, and only because I went looking:
Adom:0603X475K100CT — Symbol Editor # asked for CL21A226MPQNNNE
This is the worst failure shape available: a green flag over a plausible screenshot of the wrong component. Any caller doing batch verification will certify part N with part N-1's picture.
This is the exact shape of #42 ("P0: kicad_show_footprint with allowFocusSteal returns success:true while the PREVIOUS footprint is on screen"), which is closed — but on the symbol/library path rather than the footprint path. Whatever assertion fixed #42 does not appear to guard this one. It is also adjacent to #49 (closed: show_symbol landing on a stock symbol when the caller asked for Adom) and #54 (open: show_symbol landing on the NAME_1_1 sub-node).
Ask: return success: false with a symbol_not_found code when the name does not resolve, and include resolvedSymbol (what is actually on screen now) on every response, success or not.
Finding 2 — the symbol name inside the file is not the filename
The reason the lookup missed: CL21A226MPQNNNE.kicad_sym declares itself as
(symbol "CL21A226MPQNNN" ...)
The trailing E is dropped. The file is named for the MPN; the symbol is not. So the obvious call — ask for the part number — silently finds nothing, and Finding 1 then hides it.
My workaround is to fetch the .kicad_sym, regex the first top-level (symbol "…") (skipping _1_1 sub-units), and ask for that. Every caller will have to write this, and each one will write it slightly differently.
Ask: accept the filename/MPN as an alias, or expose kicad_list_symbols {libraryName} so a caller can resolve a name without parsing s-expressions. A resolvedSymbol echo (Finding 1) would also make the mismatch self-evident on the first call.
Finding 3 — desktop_screenshot_base64 {path} cannot read the bridge's own screenshot dir
kicad_screenshot_all writes PNGs and returns their savedTo paths, but handing one of those paths straight to desktop_screenshot_base64 is refused. The bridge's own output directory is not readable by the verb a caller would naturally use to fetch it, so evidence has to be re-captured a different way rather than collected.
Finding 4 — ten more data points for #51
Not a new report — #51 ("Library rescan verb: installing a part costs a full KiCad restart, ~150s per part") already names this, and my numbers line up with it exactly. Adding the measurements since a clean bimodal set may be useful when you size the fix:
| part | seconds |
|---|---|
| 0402B103J500CT | 67 |
| 0603B105K160CT | 75 |
| 0603X475K100CT | 149 |
| CL21A226MPQNNNE | 75 |
| CQ03SAF1004T5E | 74 |
| 0603WAF100JT5E | 151 |
| CR0402-FX-1000GLF | 149 |
| BLM15BA470SN1D | 149 |
| LQM18JNR10J00D | 149 |
| IN-S63BT5UW | 149 |
Sequential, one warm machine, same library, same three steps per part. Five at ~74s and five at 149–151s — the slow half clusters within 2 seconds of each other, which is the restart in #51 rather than anything load-dependent. It does not track part complexity: part 3 was slow while parts 4 and 5 were fast.
A progress block on kicad_show_library would at least let a caller show the human why a part is taking 150s (ab 2.0.67+ renders one in its own window). Right now "slow" and "stuck" are indistinguishable from outside.
The bigger ask, and why
Importing a library owes the caller three artifacts: symbol, footprint, and the part's 3D chip. Today kicad_show_library returns {success: true} and nothing else — no artifact paths, no statement of what it opened, no up-front hint about what evidence will exist. So the caller screenshots the app and reads the picture, which is exactly how Findings 1 and 2 stayed hidden for a full run.
What would fix the class rather than the instances:
- an up-front hint naming the artifacts the verb will produce, before it runs;
- artifact paths or handles in the response, one per artifact;
resolvedSymbolalways echoed;- a measured
progressblock.
Happy to re-run any part with extra instrumentation, or to attach the ten captures.