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.101
4 files changed
+46−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.6.1"+VERSION = "4.7.0" AI_THREAD = "kicad-dashboard" DEFAULT_PORT = 8931 UI_DIR = Path(__file__).resolve().parent / "ui"
dashboard/ui/newbie-panel.js+43−1@@ -412,6 +412,18 @@ function selfCheck(panel) { panel = panel || document.querySelector('.anp'); if (!panel) return { ok: false, error: 'no .anp panel on the page' };+ /* REFUSE TO REPORT FROM A COLLAPSED LAYOUT. An unforegrounded tab returns zero-height+ * rects while computed styles still resolve normally, so selfCheck produced EIGHT GREEN+ * ROWS beside two red ones: "panel gutter: 0px left, 744px right" and "columns: want 1,+ * got 3". That mixed shape is far more dangerous than an all-zero one, because it reads+ * as a specific layout regression rather than an invalid run, and project-manager nearly+ * filed it as a bug. A refusal cannot be misread. (project-manager, 2026-08-25.) */+ var w0 = Math.round(panel.getBoundingClientRect().width);+ if (w0 === 0) return { ok: false, invalid: true,+ error: 'panel measures 0px wide: this tab is not foregrounded, so every layout row would ' ++ 'be computed from a collapsed pane while the style rows pass normally. Activate ' ++ 'the tab by name and re-run. No rows reported, because a partial result from an ' ++ 'unrendered pane looks like a real bug.' }; var cs = getComputedStyle(panel), rows = [], ok = true; /* Chrome reports the USED border-width, snapped to whole device pixels, so a declared * 1px reads as 0.666667px at dpr 1.5. Compare against the snapped value, not the@@ -514,6 +526,36 @@ return { ok: ok, rows: rows }; } - root.AdomNewbiePanel = { mount: mount, toast: toast, selfCheck: selfCheck, copyText: copyText, version: '2.8.0',+ /* checkSend(apiBase) - prove the send path EXISTS, without sending anything.+ * gate() fails OPEN on purpose, so a broken probe cannot block a user from sending. The+ * consequence, which kicad found in itself: A MISSING GATE READS AS AN ALLOWED GATE. Its+ * /updater/status route had been lost in a rebuild, the gate got HTML, caught, and returned+ * open, so the version gate had been silently no-opping. Nothing anywhere said so.+ * This makes that visible. It never posts a prompt: the run-prompt route is probed with+ * OPTIONS, so it can report "wired" without creating a thread in anyone's list. */+ function checkSend(base) {+ base = base == null ? '' : base;+ var rows = [], ok = true;+ function add(what, want, got, pass) { rows.push({what: what, want: want, got: got, pass: pass}); if (!pass) ok = false; }+ return fetch(base + '/updater/status', {cache: 'no-store'})+ .then(function (r) { return r.text().then(function (t) { return {s: r.status, t: t}; }); })+ .then(function (res) {+ var v = null, parsed = false;+ try { var j = JSON.parse(res.t); parsed = true; v = j && j.updater && j.updater.current_version; } catch (e) {}+ add('gate route wired', '200 with JSON', res.s + (parsed ? ' JSON' : ' NOT JSON'), res.s === 200 && parsed);+ add('gate reports a version', 'updater.current_version', String(v), !!v);+ if (v) add('version meets the minimum', MIN_API.join('.'), String(v), verGte(verNum(v), MIN_API));+ })+ .catch(function (e) { add('gate route wired', '200 with JSON', 'FETCH FAILED: ' + e.message, false); })+ .then(function () {+ return fetch(base + '/ai-threads/run-prompt', {method: 'OPTIONS'})+ .then(function (r) { add('send route wired', 'not 404', String(r.status), r.status !== 404); })+ .catch(function (e) { add('send route wired', 'not 404', 'FETCH FAILED: ' + e.message, false); });+ })+ .then(function () { return {ok: ok, rows: rows}; });+ }++ root.AdomNewbiePanel = { mount: mount, toast: toast, selfCheck: selfCheck, copyText: copyText,+ checkSend: checkSend, version: '2.17.0', 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.100",+ "version": "1.0.101", "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.100",+ "version": "1.0.101", "tags": [ "kicad", "pcb",