app
Adom Library
Public Made by Adomby adom
adom-lbr — the EDA library translator. Bring a component in from any supported EDA tool and convert it to any other (KiCad ⇄ Altium ⇄ EAGLE/Fusion) through one canonical adom-lbr JSON — symbol + footprint + 3D + pin↔pad map. Altium is written natively (no Altium needed). Includes the adom-lbr Manager: browse wiki components and view symbol/footprint/3D + the per-EDA layer stackup.
← Commit history
2.11.6: Try it returns as copy-with-toast; zero /ai-threads calls
6 files changed
+37−31
Cargo.lock+1−1@@ -10,7 +10,7 @@ checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "adom-lbr"-version = "2.11.5"+version = "2.11.6" dependencies = [ "altium-codec", "anyhow",
Cargo.toml+1−1@@ -1,6 +1,6 @@ [package] name = "adom-lbr"-version = "2.11.5"+version = "2.11.6" edition = "2021" description = "adom-lbr generator / EDA translator: the canonical adom-lbr JSON is the hub, with native converters to Altium (.SchLib/.PcbLib/.IntLib), EAGLE/Fusion (.lbr), and KiCad. Altium output is written natively — no Altium needed at conversion time."
VERSION+1−1@@ -1 +1 @@-2.11.5+2.11.6
package.json+1−1@@ -1,6 +1,6 @@ { "slug": "adom-lbr",- "version": "2.11.5",+ "version": "2.11.6", "type": "app", "description": "adom-lbr \u2014 the EDA library translator. Bring a component in from any supported EDA tool and convert it to any other (KiCad \u21c4 Altium \u21c4 EAGLE/Fusion) through one canonical adom-lbr JSON \u2014 symbol + footprint + 3D + pin\u2194pad map. Altium is written natively (no Altium needed). Includes the adom-lbr Manager: browse wiki components and view symbol/footprint/3D + the per-EDA layer stackup.", "dependencies": {},
page.json+9−12@@ -1,8 +1,8 @@ { "slug": "adom-lbr",- "version": "2.11.5",+ "version": "2.11.6", "type": "app",- "description": "adom-lbr — the EDA library translator. Bring a component in from any supported EDA tool and convert it to any other (KiCad ⇄ Altium ⇄ EAGLE/Fusion) through one canonical adom-lbr JSON — symbol + footprint + 3D + pin↔pad map. Altium is written natively (no Altium needed). Includes the adom-lbr Manager: browse wiki components and view symbol/footprint/3D + the per-EDA layer stackup.",+ "description": "adom-lbr \u2014 the EDA library translator. Bring a component in from any supported EDA tool and convert it to any other (KiCad \u21c4 Altium \u21c4 EAGLE/Fusion) through one canonical adom-lbr JSON \u2014 symbol + footprint + 3D + pin\u2194pad map. Altium is written natively (no Altium needed). Includes the adom-lbr Manager: browse wiki components and view symbol/footprint/3D + the per-EDA layer stackup.", "dependencies": {}, "tags": [ "eda",@@ -52,24 +52,21 @@ ], "files": [ "bin/**",- "assets/**", "SKILL.md",- "skills/**", "README.md", "install.sh", "uninstall.sh",- "screenshots/**",- "dockbar.json"+ "screenshots/**" ],- "discovery_pitch": "Convert electronic-component symbols + footprints between any two EDA tools — KiCad, Altium (written natively, no Altium needed), and EAGLE/Fusion — through one canonical adom-lbr JSON, silk/courtyard/fab layers preserved. Plus a Manager to browse and inspect any wiki part.",+ "discovery_pitch": "Convert electronic-component symbols + footprints between any two EDA tools \u2014 KiCad, Altium (written natively, no Altium needed), and EAGLE/Fusion \u2014 through one canonical adom-lbr JSON, silk/courtyard/fab layers preserved. Plus a Manager to browse and inspect any wiki part.", "sample_prompts": [ { "prompt": "Convert this KiCad symbol and footprint to an Altium SchLib and PcbLib",- "label": "KiCad → Altium"+ "label": "KiCad \u2192 Altium" }, { "prompt": "Import this Altium footprint into the adom-lbr JSON",- "label": "Altium → JSON"+ "label": "Altium \u2192 JSON" }, { "prompt": "Bundle this part into a single Altium IntLib",@@ -77,15 +74,15 @@ }, { "prompt": "Convert this Altium SchLib and PcbLib to a KiCad symbol and footprint",- "label": "Altium → KiCad"+ "label": "Altium \u2192 KiCad" }, { "prompt": "Export this adom-lbr JSON to a KiCad .kicad_sym and .kicad_mod",- "label": "JSON → KiCad"+ "label": "JSON \u2192 KiCad" }, { "prompt": "Open the adom-lbr Manager to browse wiki components and view the layer stackup", "label": "Browse parts" } ]-}+}
src/manage.html+24−15@@ -69,6 +69,7 @@ #toast{position:fixed;left:50%;bottom:22px;transform:translateX(-50%) translateY(20px);background:#0d1117;border:1px solid var(--acc);color:var(--ink);padding:8px 14px;border-radius:9px;font-size:13px;opacity:0;transition:opacity .18s,transform .18s;pointer-events:none;z-index:2000;max-width:80vw} #toast.show{opacity:1;transform:translateX(-50%) translateY(0)} #toast.err{border-color:var(--red)}+ #toast.success{border-color:var(--green);color:var(--green)} /* ---- Settings modal: the Adom settings surface (settings-layout skill) ---- */ dialog.settings{width:min(680px,92vw);max-width:none;padding:0;overflow:hidden;border-radius:12px;background:var(--surface);border:1px solid var(--border);color:var(--text-body);box-shadow:0 20px 60px #000a} dialog.settings::backdrop{background:rgba(0,0,0,.25)}@@ -239,7 +240,7 @@ <section id="say" aria-labelledby="sayTitle" hidden> <button class="iconbtn say-close" id="sayClose" aria-label="Hide the Say it strip" title="Hide this strip. It stays hidden until you turn it back on in Settings (Say it strip)."><svg viewBox="0 0 24 24" aria-hidden="true"><path fill="currentColor" d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg></button> <div class="say-head"><h2 id="sayTitle">Say it to your AI</h2>- <span class="say-sub">You do not drive this dashboard by hand. You ask your AI, using the word <b>lbr</b>. Click a phrase to copy it, then paste it into any Adom AI thread.</span></div>+ <span class="say-sub">You do not drive this dashboard by hand. You ask your AI, using the word <b>lbr</b>. Click a phrase (or Try it) to copy it, then paste it into any Adom AI thread.</span></div> <div class="say-list" id="phrases"></div> </section> <div id="panes">@@ -641,7 +642,10 @@ loadList(); loadSample(); // ===================== dock contract: LEDs, say, settings ===================== let toastT=null;-function toast(msg,err){const t=document.getElementById('toast');t.textContent=msg;t.className='show'+(err?' err':'');clearTimeout(toastT);toastT=setTimeout(()=>t.className='',2600);}+function toast(msg,err,kind){const t=document.getElementById('toast');+ const k=kind||(err?'err':'');+ t.innerHTML=(k==='success'?'<svg viewBox="0 0 24 24" width="15" height="15" style="vertical-align:-2px;margin-right:7px" aria-hidden="true"><path fill="currentColor" d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z"/></svg>':'')+msg;+ t.className='show'+(k?' '+k:'');clearTimeout(toastT);toastT=setTimeout(()=>t.className='',k==='success'?4000:2600);} async function api(path,opts){const r=await fetch(path,Object.assign({},opts,{signal:AbortSignal.timeout(5000)}));return r.json();} // ---- live LEDs in the header, from the same /api/status the dock polls ----@@ -678,23 +682,28 @@ async function loadSay(){ (r.say||[]).forEach(p=>{ const w=document.createElement('span');w.className='phrase'; const t=document.createElement('span');t.className='txt';t.textContent=p;t.title='click to copy';- t.onclick=async()=>{toast((await copyText(p))?'Copied: "'+p+'"':'Could not copy; select it by hand',false);};- // Try it is PARKED (ship-night ruling, 2026-08-23): the run-prompt path- // can crash ah until the typing fix certifies, and /ai-threads calls wake- // ah's parked backend. Copy-only until the all-clear; flip to re-enable.- const TRY_ENABLED=false;- if(TRY_ENABLED){- const b=document.createElement('button');b.className='try';b.textContent='Try it';b.title="stage this phrase, unsent, into this app's own AI thread";- b.onclick=async()=>{- b.disabled=true;+ t.onclick=async()=>{const ok=await copyText(p);if(ok)toast('Copied to clipboard. Paste it into any AI thread.',false,'success');else toast('Could not copy; select it by hand',true);};+ // Try it copies the phrase (John's ruling, 2026-08-23): NO live AI-thread+ // opening/staging for now — zero /ai-threads calls from page or server+ // (the parked /api/try + the staging code stay dormant for the all-clear).+ const TRY_STAGING=false;+ const b=document.createElement('button');b.className='try';b.textContent='Try it';+ b.title='copies this prompt so you can paste it into any AI thread';+ b.onclick=async()=>{+ b.disabled=true;+ if(TRY_STAGING){ try{ const res=await api('api/try',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({phrase:p})}); if(res.staged){toast('Staged into '+(res.where||'your AI thread')+': "'+p+'" (press Enter there to send)');} else{await copyText(p);toast('Copied instead: '+(res.reason||'could not stage'),true);} }catch(e){await copyText(p);toast('Copied instead (dashboard could not reach the control API)',true);}- b.disabled=false;- };- w.appendChild(t);w.appendChild(b);- } else { w.appendChild(t); }+ } else {+ const ok=await copyText(p);+ if(ok)toast('Copied to clipboard. Paste it into any AI thread.',false,'success');+ else toast('Could not copy; select the phrase by hand and copy it',true);+ }+ b.disabled=false;+ };+ w.appendChild(t);w.appendChild(b); el.appendChild(w); }); }catch(e){}