app
Adom Bridge
Public Made by Adomby adom
Adom Bridge unleashes your AI onto your full PC: full power, full safety. The AI breaks out of the container it runs in and onto your real machine, managing and running your entire laptop as you: launch apps, move files, drive any window, control KiCad, Fusion 360 or your real signed-in browser. Works with any AI, cloud or local (Claude Desktop, Claude Code, Codex), no Hydrogen required. Bridge and its bridges are an operating system for AI, with managed Node and Python runtimes, and a human-onl
← Commit history
demo: the library card now proves all three artifacts (symbol + footprint + 3D), one screenshot each, and only 3/3 passes
1 file changed
+86−1
web-control-demo.html+86−1@@ -1550,6 +1550,90 @@ for (const w of mine) { // arg (0.9.108) installs the .step into 3dmodels/Adom and WIRES the // footprint's (model ...) reference itself — the page's old hand-splice is // retired; the bridge owns model wiring now.+ // A LIBRARY is a symbol PLUS a footprint PLUS a 3D model, so the proof that a+ // library works is all three of those opening - not a picture of the library+ // tree. The old card showed whatever the Symbol Editor happened to be holding+ // (ADOM_MECHANICAL_PIN, which sorts first), which proved nothing and looked+ // like the wrong part had loaded. Measured across a 10-part run: this card's+ // shot was byte-identical for 8 of the 10 parts.+ //+ // John, 2026-08-20: "a library is all 3 of those items".+ function appendPicked(c, d, pickTitle, label) {+ var shots = findShots(d).filter(function (s) { return s && (s.image || s.base64 || s.png); });+ if (!shots.length) return false;+ var want = (pickTitle || "").toLowerCase();+ var picked = want ? shots.filter(function (s) {+ return ((s.title || s.label || "") + "").toLowerCase().indexOf(want) >= 0;+ }) : shots;+ if (!picked.length) picked = [shots[shots.length - 1]];+ var s0 = picked[0];+ addShot(c.card, s0.image || s0.base64 || s0.png, label + " - " + (s0.title || s0.label || "window"));+ return true;+ }++ function showLibraryProof(c) {+ c.btn.disabled = true;+ cardLog(c.card).textContent = "";+ var sb = c.card.querySelector("div.shots"); if (sb) sb.innerHTML = "";+ setAwaiting(c.res, "asking permission (choose “Allow 1 hr”) ...",+ "on " + esc(selfLabel()) + " - opens the symbol, the footprint and the 3D model as proof",+ "on " + esc(selfLabel()) + " - opens the symbol, the footprint and the 3D model as proof");+ clog(c, "Target machine: " + selfLabel());+ startSurfaceProgress(c, "kicad_show_library");+ var results = [];+ stageKicadPart(c).then(function () {+ // Browse mode WITH symbolName actually loads the part into the canvas -+ // the bridge says so in its own hint: "To load a part into the canvas,+ // call again with symbolName too."+ clog(c, "Opening the '" + PART.kicadLib + "' library at " + (PART.kicadSymbolName || PART.name) + " ...");+ return postVerb("kicad_show_library", {+ libraryName: PART.kicadLib,+ symbolName: PART.kicadSymbolName || PART.name+ });+ }).then(function () {+ var steps = [+ { cmd: "kicad_show_symbol", label: "symbol", pick: "symbol editor",+ args: function () { return { symbolName: PART.kicadSymbolName || PART.name, library: PART.kicadLib }; } },+ { cmd: "kicad_show_footprint", label: "footprint", pick: "footprint editor",+ args: function () { return { footprintName: PART.kicadFootprintName || PART.name, library: PART.kicadLib }; } },+ { cmd: "kicad_show_3d_chip", label: "3D model", pick: "3d viewer",+ args: function () { return { footprintName: PART.kicadFootprintName || PART.name, library: PART.kicadLib }; } }+ ];+ return steps.reduce(function (chain, st) {+ return chain.then(function () {+ clog(c, "Proving the " + st.label + " ...");+ return postVerb(st.cmd, st.args()).then(function (r) {+ var jj = r.j || {};+ var ok = r.s === 200 && jj.success !== false && !jj.errorCode &&+ !(typeof jj.error === "string" && jj.error.trim() !== "");+ results.push({ label: st.label, ok: ok });+ if (!ok) {+ clog(c, " " + st.label + " FAILED: " + (jj.error || jj.errorCode || ("HTTP " + r.s)));+ return;+ }+ return settleThenCapture(c, "kicad_state").then(function (sr) {+ if (!(sr.s === 200 && sr.j && appendPicked(c, sr.j, st.pick, st.label)))+ clog(c, " (" + st.label + " opened but no capture came back)");+ });+ });+ });+ }, Promise.resolve());+ }).then(function () {+ finishSurfaceBar(c);+ var good = results.filter(function (r) { return r.ok; }).length;+ var missing = results.filter(function (r) { return !r.ok; }).map(function (r) { return r.label; });+ if (good === 3) setRes(c.res, "ok", "Done - all 3 library artifacts opened",+ "symbol + footprint + 3D model, each captured below");+ else setRes(c.res, "err", good + "/3 library artifacts opened",+ "missing: " + missing.join(", ") + " - a library is only proven when all three open");+ c.btn.disabled = false;+ }).catch(function (e) {+ finishSurfaceBar(c);+ setRes(c.res, "err", "library proof failed", (e && e.message) || String(e));+ c.btn.disabled = false;+ });+ }+ var _kicadPart = null; function stageKicadPart(c) { if (_kicadPart) { clog(c, "Part already staged this session (reusing)."); return _kicadPart; }@@ -1635,7 +1719,7 @@ for (const w of mine) { { label: function () { return "Symbol (" + PART.name + ")"; }, cmd: "kicad_show_symbol", args: function () { return { symbolName: PART.kicadSymbolName || PART.name, libraryName: PART.kicadLib }; }, stage: stageKicadPart, pick: "symbol editor", note: "installs the part from its wiki page, then shows JUST the symbol" }, { label: function () { return "Footprint (" + PART.name + ")"; }, cmd: "kicad_show_footprint", args: function () { return { footprintName: PART.kicadFootprintName || PART.name, library: PART.kicadLib }; }, stage: stageKicadPart, pick: "footprint editor", note: "just the land pattern: pads + courtyard" }, { label: function () { return "3D chip (" + PART.name + ")"; }, cmd: "kicad_show_3d_chip", args: function () { return { footprintName: PART.kicadFootprintName || PART.name, library: PART.kicadLib }; }, stage: stageKicadPart, pick: "3d viewer", note: "the part's STEP model on its footprint" },- { label: function () { return "Library tree ('" + PART.kicadLib + "') - loads no part"; }, cmd: "kicad_show_library", args: function () { return { libraryName: PART.kicadLib }; }, stage: stageKicadPart, pick: "symbol editor", note: "EXPECT A DIFFERENT PART IN THE SHOT BELOW. This verb browses the library TREE and by design loads NO part, so the editor keeps showing whatever symbol it already had (usually ADOM_MECHANICAL_PIN, which sorts first). Measured across a 10-part run: the symbol, footprint and 3D shots are all 10/10 unique, while this one is byte-identical for 8 of 10 parts. That is the verb behaving correctly, not a stale file - which is why the label no longer names the part." },+ { label: function () { return "Library (" + PART.name + " in '" + PART.kicadLib + "') - proves all 3"; }, cmd: "kicad_show_library", proof: true, stage: stageKicadPart, note: "a library IS a symbol + a footprint + a 3D model, so this opens all three and captures one screenshot of each. It reports N/3, and only 3/3 is a pass - a library with a symbol but no 3D model is not a working library." }, { label: function () { return "Schematic (just the " + PART.name + ")"; }, cmd: "kicad_show_schematic", args: function () { return { filePath: (PART.kicadProject || {}).schPath }; }, stage: stageKicadProject, pick: "schematic editor", note: "the generated single-component schematic (kicad_make_part_project)" }, { label: "2D board (part placed, tight edge cuts)", cmd: "kicad_show_2d_board", args: function () { return { filePath: (PART.kicadProject || {}).pcbPath }; }, stage: stageKicadProject, pick: "pcb editor", note: "the part-dominant board" }, { label: "3D board (real 3D body on the board)", cmd: "kicad_show_3d_board", args: function () { return { filePath: (PART.kicadProject || {}).pcbPath }; }, stage: stageKicadProject, pick: "3d viewer", note: "the populated board in 3D - the whole ladder underneath it" },@@ -1643,6 +1727,7 @@ for (const w of mine) { ].forEach(function (s) { var cc = card("grp-kicad", "verb", labelOf(s)); PART_CARDS.push({ cc: cc, label: labelFnOf(s) });+ if (s.proof) { cc.btn.onclick = function () { showLibraryProof(cc); }; return; } cc.btn.onclick = function () { showSurface(cc, { showCmd: s.cmd,