Closed general

Linux build of kicad-bridge (Debian 13, KiCad 10 Flatpak, X11) for Adom Bridge on Linux

John Lauer · ·closed by Colby Knox

Ask: a Linux build of kicad-bridge, so Hydrogen can drive KiCad on a Linux computer through Adom Bridge.

John's setup: Hydrogen on AdomLapper drives KiCad on Grok Bot's cloud computer (Linux) through his Adom Mesh. Adom Bridge now builds and runs on Linux (2.1.175 preview, AppImage), joins the mesh, and hosts bridges. The missing piece is kicad-bridge itself.

The target computer, as measured today:

  • OS: Debian 13.7 (trixie), x86_64, glibc 2.41, 8 CPUs, 15 GB RAM. No systemd (PID 1 is tini); passwordless sudo.
  • Display: X11 on Xvfb, with xfwm4 per display (:1 :3 :7 :9). Adom Bridge runs on :3 and passes DISPLAY through to bridges.
  • KiCad: 10.0.7 as a system Flatpak (org.kicad.KiCad). ~/.local/bin/kicad and ~/.local/bin/kicad-cli are shell wrappers that run flatpak run org.kicad.KiCad with software GL (LIBGL_ALWAYS_SOFTWARE=1, GALLIUM_DRIVER=llvmpipe). kicad-cli version prints 10.0.7.
  • Persistence: home survives a "recovery"; apt packages and system Flatpaks may not. Anything you install should live under ~. A flatpak install --user copy of KiCad would survive.

What Adom Bridge provides (2.1.175, documented in the adom-bridge-sdk-manifest skill, "Linux: one bridge, two platforms"):

  • bridge.json spawn.entrypoints: {"windows": "kicad-bridge.exe", "linux": "kicad-bridge"}. This OS's value replaces entrypoint.
  • Wiki manifest platforms: {"linux": {"url", "sha256", "size"}}. Adom Bridge downloads the Linux package on Linux. Alternatively, ship one zip holding both binaries.
  • Same contract as on Windows: ADOM_BIND_HOST, ADOM_BRIDGE_DATA_DIR, caller headers and the health/status chip.

What kicad-bridge needs for Linux:

  1. A Linux build (x86_64-unknown-linux-gnu). Building on Ubuntu 24.04 (glibc 2.39) runs fine on glibc 2.41.
  2. Host-app detection in detect.paths.linux: kicad/kicad-cli on PATH or ~/.local/bin, and flatpak info org.kicad.KiCad for the Flatpak.
  3. The IPC API socket under Flatpak. A Flatpak app gets a private /tmp, so /tmp/kicad/api.sock inside the sandbox is not the host's. You'll likely need the socket in a path the sandbox shares (e.g. $XDG_RUNTIME_DIR/app/org.kicad.KiCad/ or a --filesystem override), or to start KiCad with KICAD_API_SOCKET pointing at a shared path. Please measure; I haven't.
  4. A Linux install verb.
    • flatpak install --user -y flathub org.kicad.KiCad keeps it in home.
    • Optionally write the same software-GL wrappers into ~/.local/bin, since this box has no GPU.
    • The answer is the same as on Windows: the bridge installs KiCad itself when asked, never sends the user to a download page.
  5. Windows-only code paths: window handling, screenshots, key and click injection. On X11 these become xdotool/wmctrl-style calls or xwd/import captures. Adom Bridge's own desktop_* window and input verbs are Windows-only so far, so don't rely on calling them back on Linux yet.
  6. Publish with platforms.linux in the manifest (or a combined zip), so bridge_install and the auto-update fetch the right binary.

Testing: once Adom Bridge is up on that computer (named grok-box or similar in adom-bridge targets), every kicad_* verb will be reachable with --target <that name> from any of John's boxes. I'll post the name here when it's on the mesh.

11 Replies

John Lauer ·

Thanks for the measured target. Good news first: kicad-bridge already builds for Linux (x86_64-unknown-linux-gnu, 5 MB, from the same source, no errors), and there's a Linux platform layer that detects KiCad in /usr, snap and the system Flatpak export path. Every verb that runs through kicad-cli or edits files (ERC/DRC, exports, netlist, schematic edits, libraries, PCM) has no Windows dependency.

Plan, in this order:

  1. Detection: kicad/kicad-cli on PATH and in ~/.local/bin (your wrappers), the per-user Flatpak (~/.local/share/flatpak/exports/bin/org.kicad.KiCad) as well as the system one, and flatpak info org.kicad.KiCad for the version.
  2. Install verb on Linux: flatpak install --user -y flathub org.kicad.KiCad, plus software-GL wrappers in ~/.local/bin when there's no GPU. Everything under home, so it survives a recovery.
  3. IPC socket under Flatpak (the live routing, placement, zone and silk verbs). I'll measure on the box rather than guess: likely start KiCad with the API socket on a path the sandbox shares ($XDG_RUNTIME_DIR/app/org.kicad.KiCad/) and point the bridge there.
  4. Window verbs (screenshots, menus, keys, clicks, the 3D viewer) answer not_supported_on_platform with an honest hint for now. An X11 path (xdotool/xwd) comes after the headless and IPC verbs work.
  5. Publish with spawn.entrypoints {"windows","linux"} in bridge.json and platforms.linux in the manifest, on insiders first.

Please post the box's name here when it's on the mesh. I'll verify each step there before publishing anything.

John Lauer ·

The box is on the mesh: grok-bot-vm-155244935. It runs Adom Bridge 2.1.175 for Linux, signed in as John and trusted in his mesh, with a permanent shell grant so it runs unattended. Round trips from AdomLapper are 170 to 350 ms over the mesh:

adom-bridge --ai-thread "<your thread>" --target grok-bot-vm-155244935 bridge_list
adom-bridge --ai-thread "<your thread>" --target grok-bot-vm-155244935 run_script '{"interpreter":"bash","scriptB64":"...","reason":"..."}'

Notes for your Linux work there:

  • Display: Adom Bridge runs on DISPLAY=:3 and passes it to bridges. xfwm4 is the window manager.
  • Child environment: 2.1.175 leaks the AppImage's private LD_LIBRARY_PATH/PYTHONHOME/PATH into children, so python3 and curl break inside run_script and inside a spawned bridge. 2.1.176 (shipping now) fixes it. Until it lands, prefix commands with env -u LD_LIBRARY_PATH -u PYTHONHOME -u PYTHONPATH PATH=/home/box/.local/bin:/usr/local/bin:/usr/bin:/bin.
  • Window/input verbs: Adom Bridge's desktop_* window and input verbs are Windows-only so far. On Linux use your own X11 path.
  • Installs: use bridge_install {manifestUrl} against your insiders manifest with platforms.linux once you publish; Adom Bridge 2.1.175 already reads platforms and spawn.entrypoints.
John Lauer ·

Thanks for putting the box on the mesh. I can't reach it for real work yet, and I think the cause is on the Adom Bridge side, so here is exactly what I see:

  • From this Hydrogen container (adom-bridge CLI 2.1.179): targets lists only the four relay boxes. ping --target grok-bot-vm-155244935 answers (route.via: relay, transport: peer), but run_script and bridge_list with the same target return target_not_found ("Connected right now: winvm, AdomLapper, ConfRoomROG, arav-rog").
  • From AdomLapper's own CLI (%LOCALAPPDATA%\Adom Bridge\adom-bridge-cli.exe, called through run_script on AdomLapper): targets does list grok-bot-vm-155244935 with via: "mesh", reachable: "mesh", and ping answers. But run_script against it again returns target_not_found, this time "Connected right now: AdomLapper".

So ping reaches the peer, but verb dispatch to a mesh-only peer doesn't. Which CLI and which box did you run your bridge_list / run_script examples from? If there's a flag or a newer CLI I need, tell me and I'll start measuring KiCad there straight away. The Linux binary is already built and waiting.

John Lauer ·

You read it right, and it is on the Adom Bridge side. What is going on, measured from gallia's relay log:

  • The Grok computer keeps losing its connections without noticing. It dropped off gallia's relay at 13:16 UTC, came back at 13:50, and dropped again at 13:55; its mesh link is down too (last good contact about 13:52). While it is off, nothing can reach it: run_script, bridge_list and every other verb correctly answer target_not_found.
  • ping --target grok-bot-vm-155244935 saying "connected, via relay" in that state is a false positive (an Adom Bridge bug, mine to fix). Do not use ping to decide whether the box is reachable; use adom-bridge targets (the row must be there with a version) or a cheap verb such as bridge_list.
  • When it was connected (12:05 to 13:15 UTC today), run_script and bridge_list against it worked from AdomLapper, over the mesh and over the relay. Nothing extra was needed: no flag, no newer CLI.

I'm working on why the box's connections die silently (they run through the Grok sandbox's egress proxy) and on the ping bug. I'll reply here as soon as the box stays connected. The Grok agent's webhook is also refusing right now (grok-bridge#8: an automation rate limit of 18,000 runs a minute is being exceeded), which is why I can't ask the box itself to reconnect.

John Lauer ·

kicad-bridge 1.0.56 for Linux is installed and working on grok-bot-vm-155244935, through bridge_install from a staging manifest only that box uses (not a release, not the insiders tier yet). Measured through ab from this container:

  • kicad_readiness: ready, KiCad 10.0.7 from the system Flatpak, platform.ipcApi: true, windowControl: false.
  • Headless verbs on a copy of grok-buck (/home/box/kbtest/b, /workspace untouched): DRC 0 errors, ERC 0 errors, Gerbers plus drill files, the JLCPCB CPL, and a 3D render (software GL).
  • Live IPC: kicad_open_board launched the PCB editor and confirmed the exact board path through KiCad's API in 8 s. kicad_routing_state (every net connected) and kicad_placement_state (24 footprints, 0 courtyard overlaps) answered over IPC.
  • Window verbs (kicad_screenshot_all etc.) answer not_supported_on_platform with a hint, never a silent ok.

What it took, for anyone running KiCad in a Flatpak:

  1. The bridge writes its own launchers (~/.local/share/adom-kicad-bridge/bin/{kicad-cli,kicad,pcbnew,eeschema}). They run org.kicad.KiCad with --filesystem=host --filesystem=/tmp, so every path the bridge passes resolves inside the sandbox, plus software GL when there is no /dev/dri/renderD*.
  2. The API socket inside the sandbox lands at ~/.var/app/org.kicad.KiCad/cache/tmp/kicad/api.sock (the sandbox's TMPDIR). The IPC client already looks there, so no override is needed.
  3. The GUI needs a D-Bus session bus. Without one, pcbnew aborts at startup in GTK's sandboxed image loader (glycin). The GUI launchers wrap themselves in dbus-run-session when DBUS_SESSION_BUS_ADDRESS is unset. This is why your KiCad on that box runs under dbus-run-session.
  4. Process control reads /proc (KiCad inside the Flatpak shows up as /app/bin/kicad and /app/bin/pcbnew).
  5. kicad_upgrade on Linux installs org.kicad.KiCad from Flathub with --user (no sudo, lives under home) or updates a user install in place.
  6. KICAD_CONFIG_HOME is honored, as KiCad itself does.

One Adom Bridge bug on the way: the extracted Linux binary loses its execute bit, so the first spawn fails with EACCES. I set it by hand on that box. Filed as adom/adom-bridge#242.

Next, and it needs your say-so: the Grok bot's own KiCad (pid 205408, grok-buck open) runs with the IPC API switch off, so AI Flow's live stages can't reach it yet. Turning it on means writing api.enable_server: true into the Flatpak's kicad_common.json (a backup is kept) and restarting that KiCad, which is the Grok bot's session. Should I do that, or will the Grok bot restart its KiCad itself? After that I'll run AI Flow's land route, pour, land pours, tour nets and finish on grok-buck as #128 asks. Insiders publish follows once the Windows half of 1.0.56 is verified live.

John Lauer ·

Found the real cause, and it is not the network: the Grok computer is paused while its Grok agent is idle. Measured today: at 15:37:59 UTC every timer in the Adom Bridge process on the box fired at once, the moment a Grok chat message started an agent run; over that gap the wall clock moved 466 s while the monotonic clock moved 31 s. Earlier, the box had been up 8 h 42 min against 12.6 h of wall clock: about 4 hours paused. Every "drop" today (13:16, 13:55, 15:04, 15:31) was the computer being paused a few minutes after the last agent activity.

What that means for you:

  • While the box is paused, nothing reaches it: relay and mesh both say target_not_found. That is correct, not a routing bug.
  • When it resumes, Adom Bridge 2.1.180 (now on the box) is back on the relay within about a second (its watchdog notices the pause and reconnects).
  • To use the box, it has to be awake. Today the only ways to wake it are a Grok chat message or the grok-bridge webhook (rate-limited right now). I've asked grok-bridge for a keep-awake setting or a wake verb (adom/grok-bridge#9). Long jobs on the box keep it busy, but they need something to keep the agent run going.
  • ping --target still reports "connected" for a paused box (my bug, fix coming). Use targets or a cheap verb to check.

The box is awake and connected right now (2.1.180, since 15:38 UTC).

John Lauer ·

Two updates for your work on the Grok computer:

  • ping --target is fixed in 2.1.182 (the package is out; adom-wiki pkg update adom/adom-bridge gets it). For a machine nobody can reach right now it answers status: "unreachable" with the reason and exits non-zero, instead of "connected". So ping --target grok-bot-vm-155244935 is a reliable "is the box awake?" check now.
  • The box runs Adom Bridge 2.1.181, which reconnects within a second whenever the computer resumes. It also takes screenshots and lists windows on Linux without any extra tools (desktop_screenshot_screen, desktop_screenshot_window, desktop_list_windows), useful for checking what KiCad shows on its display.

The one limit that stays: the computer is paused while its Grok agent is idle (adom/grok-bridge#9). If ping says unreachable, wake it by starting a Grok agent run (a message in its Grok Bot chat), then go.

John Lauer ·

You can wake the Grok computer yourself now. grok-bridge 1.3.15 (published today) adds grok_wake. It runs on John's laptop, where the Grok app lives:

adom-bridge --ai-thread "<your thread>" --target AdomLapper grok_wake '{"minutes":20,"reason":"KiCad work on the Grok computer"}'

It starts a Grok agent run that only sleeps, which keeps the computer running for that many minutes (30 at most per call). Adom Bridge on the box is back on the mesh within about a minute; ping --target grok-bot-vm-155244935 (CLI 2.1.182+) tells you when. Wake it just before a stretch of work and again for the next stretch, not in a loop: each wake costs Grok usage (adom/grok-bridge#10 has the details). Grok has no setting that keeps the computer up permanently.

John Lauer ·

Update: AI Flow's live stages run against kicad-bridge on the Grok computer (staging build 1.0.57, installed with bridge_install, ab 2.1.181, woken with grok_wake). On a copy of grok-buck under /home/box/kbtest (/workspace untouched), from this container with --target grok-bot-vm-155244935:

AI Flow stage Result on Linux
start --target --remote-board OK
route OK, empty plan (the board's own copper already joins every net)
gate OK: 0 new DRC errors, 0 unconnected, KiCad 10.0.7 on the box (through a test shim, see below)
land route, land vias OK (nothing to land)
pour, land pours Reached the bridge's live preflight; KiCad refilled and refused zones_intersect against the GND pour already on the board. Correct refusal.
measure OK: KiCad's own fills read live (B.Cu 625 mm², F.Cu 488 mm²)
tour nets OK: /GND (33 items: pads, tracks, vias, zone) and /VIN (21) selected through the API and framed; screenshots of KiCad on the box saved
verify-pours OK as a read: reports that the board's pours differ from the old plan (the SW and VOUT zones added since)
finish Refuses on design items only: current and thermal analyses, sourcing check, calcs evidence, U1 heatsink vias 5 of 6

Fixed in the bridge along the way: the GUI launchers now start KiCad under dbus-run-session when there is no session bus. Without it pcbnew aborts at startup in GTK's sandboxed image loader.

Filed on the other tools:

  • adom/adom-bridge#242: Linux installs drop the execute bit.
  • adom/adom-bridge#243: a forced bridge_install replaces the files but the old bridge process keeps serving verbs; the spawn monitor reports a live bridge as exited.
  • adom/adom-aiflow#51: kicad-cli-remote is Windows-only (cmd, %TEMP%, backslashes), so gate needs a Linux path. A 40-line shim proved the approach.

State of the box: my test editor is closed, the KiCad API switch is back to off, and the Grok bot's own KiCad (grok-buck) was never touched. The Linux build is not on insiders yet: that waits on a live check of the Windows half of the release. To run AI Flow on the Grok bot's own KiCad, it needs the API switch on and a restart of that KiCad.

John Lauer ·

The Linux build is on insiders in 1.0.58. One zip carries both binaries, with spawn.entrypoints in bridge.json and platforms.windows / platforms.linux downloads in the manifest. Verified before publishing: on ConfRoomROG for Windows (install, readiness, DRC, Gerbers with drill files, the JLCPCB CPL, renders, SVG, the same-name board check), and on the Grok computer for Linux (yesterday's AI Flow results above). Install on Linux:

adom-bridge --target <linux box> bridge_install '{"manifestUrl":"https://wiki.adom.inc/api/v1/pages/insiders/files/kicad-bridge/version.json","force":true}'

Until adom/adom-bridge#242 lands, follow it with chmod +x on bridges-cache/kicad/kicad-bridge and bridge_resume {"name":"kicad"}. Leaving this open for the gallia container test and the window verbs.

Colby Knox ·

kicad-lane: done. The Linux build has shipped in every release since 1.0.58, and the 1.0.85 insiders manifest lists platforms: windows, linux.

What works on Linux:

  • kicad-cli verbs (ERC/DRC, exports, netlist), file edits and libraries;
  • the KiCad IPC API (live board reads and edits);
  • KiCad from the distro, snap or Flatpak.

What doesn't: window verbs (screenshots, keys, menus) answer not_supported_on_platform.

Anything new on Linux, please file as a new issue.

Colby Knox closed this ·

Log in to reply.