← Commit history

2.0.4: selfCheck accepts declared OR snapped border width (failed correct panels at dpr 1.5); serve-as-a-file and same-origin-proxy are now the documented defaults

John Lauer ·fe4548d169 ·1mo ago ·parent 1b592a8
3 files changed +61−15
assets/module/newbie-panel.js+17−7
@@ -374,13 +374,23 @@     }     Object.keys(CANON).forEach(function (k) {       var want = CANON[k][1];-      if (want.indexOf('snap:') === 0) want = snap(parseFloat(want.slice(5)));-      var got = cs[CANON[k][0]];-      /* compare numerically with a sub-pixel tolerance: Chrome prints 0.666667px where the-       * arithmetic gives 0.6666666666, and a string compare fails a panel that is correct */-      var pass = (parseFloat(want) && parseFloat(got))-        ? Math.abs(parseFloat(got) - parseFloat(want)) < 0.01-        : got === want;+      var got = cs[CANON[k][0]], declared = CANON[k][1];+      /* Border widths need BOTH candidates accepted. Chrome reports the USED width, snapped+       * to whole device pixels, on some surfaces (ah's webview and pup on a dpr-1.5 laptop+       * both return 0.666667px for a declared 1px) and reports the DECLARED width on others+       * (an emulated dpr returns 1px at every ratio). Accepting only one of the two fails a+       * correct panel in the other environment, and at dpr 1.5 specifically, which is the+       * machine this fleet is reviewed on. Found by nb, 2026-08-25. */+      var pass;+      if (declared.indexOf('snap:') === 0) {+        var d = parseFloat(declared.slice(5)), g = parseFloat(got);+        pass = Math.abs(g - d) < 0.01 || Math.abs(g - parseFloat(snap(d))) < 0.01;+        want = d + 'px or ' + snap(d);+      } else {+        pass = (parseFloat(want) && parseFloat(got))+          ? Math.abs(parseFloat(got) - parseFloat(want)) < 0.01+          : got === want;+      }       if (!pass) ok = false;       rows.push({ what: k, want: want, got: got, pass: pass });     });
package.json+1−1
@@ -1,6 +1,6 @@ {   "slug": "adom-ui-design",-  "version": "2.0.3",+  "version": "2.0.4",   "type": "skill",   "description": "The Adom UI Design System plus a bundle of focused UI skills (tooltips, floating-windows, toasts, responsive-ui, app-shell, ai-driven-apps, clickable-paths, dark-default, input-feedback, settings-layout). One install drops the whole set of skill files onto your container, plus shared icon assets (the settings cog) so every Adom app draws the same glyph.",   "dependencies": {},
skills/newbie-panel/SKILL.md+43−7
@@ -55,10 +55,38 @@ column. Every one of those apps had read this skill. **A written spec is not a m </script> ``` -Serve the file next to your dashboard, or inline its text into your page if you build the-page as one string. **If you inline it, inline it verbatim.** Do not reformat it and do not-"fix" its regexes: it builds them with `RegExp()` precisely because a page assembled as a-template literal turns `\b` into a backspace and eats the word boundaries silently.+### SERVE IT AS A FILE. DO NOT INLINE IT.++Give it its own route (`/newbie-panel.js`) and `<script src>` it, even when your dashboard is+built as one big template literal. **Especially** then. pup, nb and project-manager each+arrived at this independently on the same afternoon, and pup's reason is the one that+settles it: that repo has shipped the template-literal escape bug twice, and while adopting+the module it found a THIRD instance, inside the comment warning about the bug. The module+builds its regexes with `RegExp()` so a literal `\b` can never be eaten, but that only+protects the regexes someone thought about. A file route cannot be mangled at all.++Verify the bytes you serve match the pack: `md5sum` or `sha256sum` the served file against+`~/.claude/skills/adom-ui-design/assets/module/newbie-panel.js`. project-manager and pup both+did this and both reported a byte-for-byte match, which is the check that makes "I serve the+module" mean something.++### PROXY THE TWO API CALLS THROUGH YOUR OWN SERVER++`apiBase` defaults to `''`, same origin, and it should stay that way. Add two routes to your+own server and forward them to the Hydrogen control API using whatever discovery you already+have (`~/.adom/hydrogen-control-url`, 47084 as the fallback):++```+GET  /updater/status        ->  control API /updater/status+POST /ai-threads/run-prompt ->  control API /ai-threads/run-prompt   (120s, matching the module)+```++Three reasons, and parts-search, nb and pup each found them separately: it removes any CORS+dependency on ah; it keeps exactly ONE copy of the send logic in the fleet rather than one+per app; and it keeps working in both deployment shapes, the container-served dashboard and+the desktop-bridge-served one, where a direct fetch to the control port would be cross-origin+or unreachable. The dynamic control port also stays server-side rather than being baked into+a page.  **What the module owns, so you cannot get it wrong:** the card and its accent edge, the heading and explainer, the two-column grid and its collapse, the table, the row height, the@@ -105,9 +133,17 @@ Copy icons resolve to a single x-position, the column count against the panel's whether the phrase typeface is really Satoshi rather than a silent `system-ui` fallback. `ok: true` is the conformance evidence. Nothing else counts. -It compares border widths against the **device-pixel-snapped** value, because Chrome-reports a declared `1px` as `0.666667px` at dpr 1.5. A naive string compare fails every-panel in the fleet, including a correct one. That bug was in the checker's first version.+**Border widths accept EITHER the declared or the device-pixel-snapped value**, and it took+two passes to get right. Chrome reports the USED border-width on some surfaces (ah's webview+and pup on John's dpr-1.5 laptop both return `0.666667px` for a declared `1px`) and the+DECLARED width on others (an emulated dpr returns `1px` at every ratio). The first version+compared strings and failed every correct panel. The second corrected for the snap and then+failed every correct panel in the OTHER environment, at dpr 1.5 specifically, which is the+machine this fleet is reviewed on. nb swept the ratios and caught it. Accept both candidates.++The general lesson, which pup reports cost it three wrong diagnoses on an unrelated bug the+same day: **comparing a computed style as a STRING is almost always wrong.** Compare+numerically, with a tolerance.  ### Where 700 comes from, and why it is a PANEL width