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
1.0.115: demo pill follows the desktop remote (stop closes it with a toast, mute face mirrored), mute is session-only and announced on Play, toasts stack above the pill
2 files changed
+11−5
dashboard/ui/index.html+10−4@@ -634,7 +634,7 @@ function doMount(phrases){ } // Guided demo with a REAL progress bar + the stepShot stream (one screenshot per finished beat). async function startDemo(){- toast('starting the guided demo (background)');+ toast(demoMuted()?'starting the guided demo MUTED (narration off): click the speaker on the pill or the remote to unmute':'starting the guided demo'); $('#demoShots').innerHTML=''; const s=await act('demo',{muted:demoMuted()});const d=s.data||s; if(d.success===false){toast('demo failed to start: '+(d.error||'unknown'),'err');return;}@@ -653,7 +653,11 @@ async function startDemo(){ c.innerHTML='<img src="data:image/png;base64,'+q.stepShot.image+'" alt="'+(q.stepShot.title||'')+'"><div class="cap">'+(q.stepShot.title||q.stepShot.step||'')+'</div>'; $('#demoShots').appendChild(c); }- if(q.done){clearInterval(poll);$('#demoToolbar').style.display='none';document.body.classList.remove('demo-running');toast(q.error?('demo failed: '+q.error):(q.result&&q.result.exited?'demo stopped':'demo complete'),'' + (q.error?'err':'ok'));refresh(true);}+ // Mirror the desktop remote: mute face, and a STOP (the remote's X) hides+ // this pill at once with a toast, before the bridge finishes the beat in flight.+ if(typeof q.muted==='boolean'){$('#dtMute').dataset.muted=q.muted?'1':'0';$('#dtMute').innerHTML=q.muted?'🔇':'🔊';}+ if(q.stopping&&!$('#demoToolbar').dataset.closing){$('#demoToolbar').dataset.closing='1';$('#demoToolbar').style.display='none';document.body.classList.remove('demo-running');toast('closing the demo tour','ok');}+ if(q.done){clearInterval(poll);$('#demoToolbar').style.display='none';document.body.classList.remove('demo-running');delete $('#demoToolbar').dataset.closing;toast(q.error?('demo failed: '+q.error):(q.result&&q.result.exited?'demo stopped':'demo complete'),'' + (q.error?'err':'ok'));refresh(true);} },3000); } // Demo transport: mirrors the ab toast buttons; the bridge applies commands@@ -982,10 +986,12 @@ function maybeCountLaunch(st){ // ── dash-demo player: toolbar wiring ─────────────────────────────────────── const MUTE_KEY='kdDemoMuted';-function demoMuted(){try{return localStorage.getItem(MUTE_KEY)==='1'}catch(e){return false}}+// John, 2026-09-03: a mute remembered across sessions silently started every later tour without+// audio. Mute now lives for THIS page session only, and Play says so when it starts muted.+function demoMuted(){try{return sessionStorage.getItem(MUTE_KEY)==='1'}catch(e){return false}} function setMuteUI(){$('#dtMute').classList.toggle('muted',demoMuted());} $('#dtMute').onclick=async()=>{- const m=!demoMuted();try{localStorage.setItem(MUTE_KEY,m?'1':'0')}catch(e){}+ const m=!demoMuted();try{sessionStorage.setItem(MUTE_KEY,m?'1':'0')}catch(e){} setMuteUI();await act('demo_control',{cmd:m?'mute':'unmute'}); toast(m?'narration muted':'narration on','ok'); };
package.json+1−1@@ -1,6 +1,6 @@ { "slug": "kicad-bridge",- "version": "1.0.114",+ "version": "1.0.115", "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": [