skill
Adom UI Design System
Public Made by Adomby adom
How the AI builds and tests interfaces people love to use in Adom. Ships as one installable skill that bundles focused skills (tooltips, floating-windows, toasts, responsive-ui, app-shell, ai-driven-apps, clickable-paths).
← Commit history
2.16.0: checkSend() makes a missing send gate visible; retire by port ownership not argv (kicad killed a bystander); assert on every string replacement
4 files changed
+90−3
assets/module/newbie-panel.js+31−1@@ -514,6 +514,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.16.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": "adom-ui-design",- "version": "2.15.0",+ "version": "2.16.0", "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/dash-screenshot/SKILL.md+12−1@@ -153,7 +153,18 @@ that verifies, waits and narrates. Its guard: disturbance **And the half that caused fusion's bug: the check must run IMMEDIATELY BEFORE EACH native-event, not once per sequence.** Three clicks means three verifications, because focus can move+event, not once per sequence.** fusion corrected the record on itself here, and the truth is+worse than the generous reading: it did not do one stale check, it did **ZERO**. It looked at+the foreground only AFTER the third click failed, and only because it was hunting an unrelated+symptom. **Had a toast fired on click one it would have reported success and never looked**,+and three clicks into John's live apps would have gone unnoticed and unreported.++That sharpens the rule rather than softening it: **the check must be structural, because the+failure is silent on the side that matters.** A stray click produces no error, no rejection and+no log. The only signal was an absence, and absences are exactly what a busy operator does not+notice. Note too that two independent coordinate computations agreeing to the pixel read, to+fusion, as strong evidence that coordinates were the variable. **They were the only part that+was never wrong.** Three clicks means three verifications, because focus can move between event one and event two. A single up-front check followed by three dispatches is exactly the shape that puts half a password in the wrong window.
skills/newbie-panel/SKILL.md+46@@ -606,6 +606,52 @@ If your page needs a wider margin for its own content, put it on the app body BE not on the container the panel mounts in. The panel is the full-width band at the top; the app's own gutter is the app's business. +### ⛔ A MISSING GATE READS AS AN ALLOWED GATE. PROBE IT WITH `checkSend()`.++`gate()` fails OPEN on purpose, so a broken probe cannot stop a user sending. The consequence+is invisible and kicad found it in itself: its `/updater/status` route **had been lost in a+rebuild**, so the gate received HTML, caught, and returned open. Its version gate had been+silently no-opping, and nothing anywhere said so. It could not have found this by reading its+own code, **because the code it was reading no longer existed.**++```js+await AdomNewbiePanel.checkSend() // -> {ok, rows:[gate wired, version, minimum, send wired]}+```++**It never posts a prompt.** The run-prompt route is probed with `OPTIONS`, so it reports+"wired" without creating a thread in anyone's list. Negative-controlled before shipping: with+no routes it goes red on all three; with a stub gate and a wired POST it goes green.++Run it beside `selfCheck`. `selfCheck` proves the panel is right; `checkSend` proves the button+on it can do anything.++### ⛔ RETIRE BY PORT OWNERSHIP, NEVER BY argv. kicad KILLED A BYSTANDER.++Rehearsing its upgrade (above) against a real predecessor, kicad's retirement retired the old+instance on the target port **and killed an unrelated instance serving a different port**,+because it selected victims by argv and **every instance of a tool has identical argv**. On+John's box that is a dock dashboard dying because someone upgraded something else.++The fix, and the shape to copy: **resolve the listening socket's inode from `/proc/net/tcp`,+map it to a pid via `/proc/*/fd`, and use argv only as a SAFETY FILTER on that single pid.**+Publish your own pid in `/health` so a successor has a direct path, while not depending on it,+since a predecessor may not.++Re-rehearse all three cases: mismatch retires **and the bystander survives**; match returns the+SAME pid with no restart; a foreign server holding the port is **refused with a readable error+rather than killed**.++This skill already said "argv is a claim, not a fact". kicad had implemented the claim, which+is the usual distance between reading a rule and having followed it.++### ⛔ ASSERT ON EVERY STRING REPLACEMENT++kicad's lost route came from a silent string-replace with no assertion, the same shape as the+CSS deletions that cost it earlier in the day. **And it nearly re-shipped the same defect: its+first fix "applied" against an anchor that had drifted, and only the fidelity tool's second red+run caught it.** Asserting on every replacement is the cheap habit; a tool is what catches you+when the habit fails. Have both.+ ### Prove it in one call ```js