← Commit history

Publish 1.0.101

John Lauer ·7f55aae44d ·1mo ago ·parent 0aca6d2
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",