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
kicad-dashboard: page served on any non-API path (adom.cloud proxy strips querystrings; path-params for status), live-verified render with all 8 LEDs green
1 file changed
+14−7
dashboard/kicad_dashboard.py+14−7@@ -173,7 +173,7 @@ const NAMES={relay:'Relay',box:'Box',bridge:'Bridge',kicad:'KiCad',plugin:'Plugi let cur=null; async function refresh(force){ const t=document.getElementById('target').value||'';- const r=await fetch('/api/status?target='+encodeURIComponent(t)+(force?'&force=1':''));+ const r=await fetch('api/status/'+encodeURIComponent(t||'-')+(force?'/force':'')); const d=await r.json(); cur=d; document.getElementById('gen').textContent='updated '+d.generatedAt; const sel=document.getElementById('target');@@ -188,12 +188,12 @@ async function refresh(force){ async function setSetting(){ const t=document.getElementById('target').value||''; const v=document.getElementById('overlay').checked;- await fetch('/api/settings',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({target:t,overlayBadges:v})});+ await fetch('api/settings',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({target:t,overlayBadges:v})}); toast('Overlay badges '+(v?'ON':'OFF')); } function toast(m){const e=document.getElementById('toast');e.textContent=m;e.style.display='block';setTimeout(()=>e.style.display='none',2500);} async function loadPrompts(){- const r=await fetch('/api/prompts');const ps=await r.json();+ const r=await fetch('api/prompts');const ps=await r.json(); const el=document.getElementById('prompts'); ps.forEach(([t,p])=>{el.insertAdjacentHTML('beforeend',`<div class="prompt"><div class="t">${t}</div><pre>${p}</pre><button onclick="navigator.clipboard.writeText(this.previousElementSibling.textContent).then(()=>toast('Copied'))">Copy</button></div>`);}); }@@ -215,7 +215,7 @@ class Handler(BaseHTTPRequestHandler): def do_GET(self): u = urlparse(self.path)- if u.path == "/" or u.path == "/index.html":+ if not u.path.startswith("/api") and u.path != "/health": body = PAGE.encode() self.send_response(200) self.send_header("Content-Type", "text/html; charset=utf-8")@@ -226,10 +226,17 @@ class Handler(BaseHTTPRequestHandler): self._json({"ok": True, "app": "kicad-dashboard"}) elif u.path == "/api/prompts": self._json(PROMPTS)- elif u.path == "/api/status":+ elif u.path.startswith("/api/status"):+ # params ride the PATH (/api/status/<target>[/force]) — the+ # adom.cloud proxy 404s querystring requests on subpaths.+ parts = [p for p in u.path.split("/") if p][2:] q = parse_qs(u.query)- target = (q.get("target") or [""])[0] or DEFAULT_TARGET or (get_targets() or [None])[0]- if q.get("force"):+ _p0 = (parts[0] if parts else "")+ if _p0 == "-":+ _p0 = ""+ target = (_p0 or (q.get("target") or [""])[0]+ or DEFAULT_TARGET or (get_targets() or [None])[0])+ if "force" in parts or q.get("force"): with _cache_lock: _cache["t"] = 0 self._json(cached_status(target))