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
Publish 1.0.102
5 files changed
+68−4
dashboard/kicad_dashboard.py+1−1@@ -49,7 +49,7 @@ from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer from pathlib import Path from urllib.parse import unquote, urlparse -VERSION = "4.7.0"+VERSION = "4.7.1" AI_THREAD = "kicad-dashboard" DEFAULT_PORT = 8931 UI_DIR = Path(__file__).resolve().parent / "ui"
dashboard/ui/newbie-panel.js+32−1@@ -519,6 +519,37 @@ * fleet mismatch comes back in a form the check is blind to. This asserts the panel's * left edge against the PANE, which covers the whole ancestor chain in one number. * (parts-search, 2026-08-25, reasoning about what the new yardstick still could not see.) */+ /* PHRASE HEADROOM AS A ROW, not a console warning nobody reads: "does not truncate TODAY"+ * and "has room" are different claims.+ * MEASURE need AGAINST AN OFFSCREEN nowrap PROBE. Do NOT use clientWidth - scrollWidth:+ * for a block span with overflow:hidden, scrollWidth is max(clientWidth, content), so that+ * expression SATURATES AT 0 for anything that fits, whether it fits by 1px or by 180px. It+ * still goes negative correctly when text overflows, so it looks like a working metric.+ * Two apps independently reported "0px headroom, one character from truncating" off it;+ * remeasured with this probe, neither had less than 141px of slack. A metric that can only+ * return one value on success is not evidence of success. */+ var spans = [].slice.call(panel.querySelectorAll('.anp-phrase span'));+ if (spans.length) {+ var probe = document.createElement('span');+ probe.style.cssText = 'position:absolute;visibility:hidden;white-space:nowrap;font:' ++ getComputedStyle(spans[0]).font;+ document.body.appendChild(probe);+ var worst = 0, worstTxt = '', tight = 0;+ spans.forEach(function (sp) {+ probe.textContent = sp.textContent;+ var need = Math.ceil(probe.getBoundingClientRect().width);+ var have = Math.round(sp.getBoundingClientRect().width);+ var slack = have - need;+ if (worstTxt === '' || slack < worst) { worst = slack; worstTxt = sp.textContent.trim().slice(0, 40); }+ if (slack < 8) tight++;+ });+ probe.remove();+ var headOk = worst >= 8;+ if (!headOk) ok = false;+ rows.push({ what: 'phrase headroom', want: 'at least 8px of slack on every phrase',+ got: worst + 'px on ' + JSON.stringify(worstTxt) + (tight > 1 ? ' (' + tight + ' tight)' : ''),+ pass: headOk });+ } var fam = getComputedStyle(panel.querySelector('.anp-phrase span') || panel).fontFamily; var famOk = /Satoshi/.test(fam); if (!famOk) ok = false;@@ -556,6 +587,6 @@ } root.AdomNewbiePanel = { mount: mount, toast: toast, selfCheck: selfCheck, copyText: copyText,- checkSend: checkSend, version: '2.17.0',+ checkSend: checkSend, version: '2.19.1', TWO_COL_MIN: TWO_COL_MIN, PHRASE_BUDGET: PHRASE_BUDGET }; })(typeof window !== 'undefined' ? window : this);
package.json+1−1@@ -1,6 +1,6 @@ { "slug": "kicad-bridge",- "version": "1.0.101",+ "version": "1.0.102", "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.101",+ "version": "1.0.102", "tags": [ "kicad", "pcb",
skills/kicad-bridge-dev/SKILL.md+33@@ -425,6 +425,39 @@ the package. Two layers, two commands, every time. Every one of these came from shipping something that looked verified and was not. +**A metric that returns one value on success proves nothing (2026-08-25).** I+reported "0px phrase headroom, one character from truncating" to the fleet, f7+shipped a whole new selfCheck row for it, and a second app "independently+confirmed" the same 0px. All of it was an artifact. I measured headroom as+`span.clientWidth - span.scrollWidth`, and for a block span with+`overflow:hidden`, `scrollWidth` is `max(clientWidth, content width)`: it returns+EXACTLY 0 for anything that fits, by 1px or by 180px. It saturates. The true+slack on those same six phrases was 141-180px. The second app matched me because+it used the same expression, not because the finding was real - two saturated+readings are one bug reported twice, never a confirmation. Measure width against+an OFFSCREEN nowrap probe (`position:absolute;visibility:hidden;white-space:nowrap`+with the span's computed `font`), which is what the fixed 2.19.0 row does. Before+reporting an unhealthy number, ASK WHAT A HEALTHY ONE LOOKS LIKE - here the answer+was "also 0", and that would have killed the report on the spot. Corollary: when+every value in a set ties, "the minimum" is just DOM order, which is why I named+the wrong phrase as the worst one (the real worst was "show me the board in kicad 3d").++**Force a collapsed pane OPEN before you measure it.** Same family as the+unforegrounded-tab trap. `.anp` carries `hidden`, and every rect in a hidden+subtree is 0, so the first run of the probe above returned `have: 0` and slack+-164 on all six rows - which reads exactly like catastrophic truncation. Set+`panel.hidden = false` (or call the instance's `open()`) and re-measure. Zero is+almost never a measurement; it is the shape of "you measured nothing".++**You can measure a fleet layout claim offline, honestly, if the font travels.**+newbie-panel embeds Satoshi as a base64 woff2, so the font program in my container+is byte-identical to John's. Serving the REAL page (`kicad_dashboard.py serve`) and+loading it in the puppeteer Chrome at `--window-size=734,...` reproduces his exact+geometry (scroller 734, panel 702, 2 columns) with no slot on his machine and no+bridge call. `/usr/bin/chromium-browser` is a snap stub that does not run; use+`~/.cache/puppeteer/chrome/linux-*/chrome-linux64/chrome`. Say plainly that the+number came from headless Chrome, not from his browser.+ **Your container is not a user's container.** `kicad-dashboard` "existed" for months as a 104-byte hand-written wrapper pointing at a dev clone, so `skip_if: command -v kicad-dashboard` reported SKIP on the maintainer's box and RUN on