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
v0.9.69: FIX caller identity read — AD delivers it in args.caller.aiThread (--ai-thread flag), not X-Adom-Caller-* headers. set_from_request() reads args first, headers as fallback. Found live on AdomLapper 1.9.183.
6 files changed
+35−8
BRIDGE_VERSION+1−1@@ -1 +1 @@-0.9.68+0.9.69
adom-bridge-kicad-manifest.json+5−5@@ -1,15 +1,15 @@ { "manifest_version": 1, "name": "kicad",- "version": "0.9.68",- "url": "https://wiki.adom.inc/download/adom/adom-desktop-kicad-bridge/0.9.68/adom-bridge-kicad-v0.9.68.zip",- "sha256": "3ef797c8bf20ce21aaafbc43e5c79baef2fb137242ae392497ca58428f03e382",- "size": 365433,+ "version": "0.9.69",+ "url": "https://wiki.adom.inc/download/adom/adom-desktop-kicad-bridge/0.9.69/adom-bridge-kicad-v0.9.69.zip",+ "sha256": "9f8f6ae26a034c9bf4e97a30b218659bffa30a8cac9b92c2a0acd0129954b6d8",+ "size": 365869, "verbPrefixes": [ "kicad_" ], "healthEndpoint": "/status",- "released_at": "2026-07-25T13:54:24Z",+ "released_at": "2026-07-25T14:13:50Z", "hero": "https://wiki.adom.inc/blob/app/adom-desktop-kicad-bridge/kicad-hero.png", "languages": [ "Python",
adom-bridge-kicad-v0.9.69.zipadded⋯ 1 unchanged line ⋯
bridge.json+1−1@@ -2,7 +2,7 @@ "manifest_version": 1, "name": "kicad", "displayName": "KiCad EDA",- "version": "0.9.68",+ "version": "0.9.69", "description": "Reverse bridge for KiCad \u2014 board/schematic introspection, lint via kicad-cli, plugin install, multi-instance probe, in-process DRC.", "homepage": "https://wiki.adom.inc/adom/adom-desktop", "author": "Adom Inc.",
caller_identity.py+27@@ -25,6 +25,33 @@ _HEADERS = ("X-Adom-Caller-Thread", "X-Adom-Caller-Container", "X-Adom-Caller-Re DELEGATE = "kicad" +def set_from_request(headers, args) -> dict:+ """Capture the caller from an incoming relay request.++ AD delivers caller identity TWO ways and we must read BOTH:+ * INBOUND relay (AD -> bridge): the CLI's --ai-thread flag and any explicit+ `caller` in args arrive as `args["caller"] = {"aiThread", "containerName",+ "source"}`. This is what actually shows up in practice (verified on+ AdomLapper 1.9.183, 2026-07-25) — NOT the X-Adom-Caller-* headers.+ * Header form (X-Adom-Caller-*): the shape AD uses on its OWN direct-API+ callbacks and what the SDK examples forward. Read it as a fallback so we+ also work if a future AD stamps the relay path with headers.++ args wins when both are present (it carries the explicit/flag identity).+ """+ ident = {h: (headers.get(h, "") or "") for h in _HEADERS} if headers else {h: "" for h in _HEADERS}+ caller = (args or {}).get("caller") or {}+ if isinstance(caller, dict):+ if caller.get("aiThread"):+ ident["X-Adom-Caller-Thread"] = caller["aiThread"]+ if caller.get("containerName"):+ ident["X-Adom-Caller-Container"] = caller["containerName"]+ if (args or {}).get("reason") and not ident["X-Adom-Caller-Reason"]:+ ident["X-Adom-Caller-Reason"] = args["reason"]+ _current.ident = ident+ return ident++ def set_from_headers(headers) -> dict: """Capture the caller headers off an incoming request. `headers` is anything with .get() (http.server's message object). Returns the captured dict."""
server.py+1−1@@ -844,7 +844,7 @@ class KiCadBridgeHandler(BaseHTTPRequestHandler): # AD 1.9.180: stamp WHO asked (self-asserted; logging/UX/arbitration only, # never authorization). Kept for the life of this request so any AD # callback we make while serving it can forward the identity (AD 1.9.183).- caller = caller_identity.set_from_headers(self.headers)+ caller = caller_identity.set_from_request(self.headers, args) print(f"[KiCad Bridge] {command}{caller_identity.log_suffix()} | Args: {json.dumps(args)}") try: