← Commit history

web-control handoff: altium_install_library_bundle acceptance test + Colby handoff + sample bundle

John Lauer ·791fda636d ·1mo ago ·parent 1ba1f14
3 files changed +91
LAN7800-bundle.zipadded
⋯ 1 unchanged line ⋯
docs/HANDOFF-COLBY.mdadded+29
@@ -0,0 +1,29 @@+# Altium ⇄ web control — handoff (John's altium thread → Colby, 2026-08-31)++Goal: light up the **Altium** chip in the EXPORTS TO row on component/molecule pages, next to your KiCad and Fusion buttons.++## What already works (verified on a real AD 26.9.1 box)++`adom/altium-bridge` v0.1.7 ships **`altium_install_library_bundle`** — the exact peer of `kicad_install_library_bundle`:++```js+AdomWebControl.run('altium_install_library_bundle', {+  zipPath: staged,          // from your write_file / write_file_chunk staging, unchanged+  libraryName: 'LAN7800',   // ^[A-Za-z0-9][A-Za-z0-9 ._-]{0,63}$+  capture: true, captureMaxWidth: 480+})+// → { success, library, symbols, footprints, intlibs, installed:[{lib,ok}],+//     altiumRunning, restartNeeded, thumbnailDataUrl?, proofSkipped? }+```++Bundle zip = `<Lib>.SchLib` + `<Lib>.PcbLib` (or a compiled `<Lib>.IntLib`), wrapping folder tolerated. Hardened: zip-slip guard, 256 MB zipped / 512 MB unpacked caps, name regex. Restart contract identical to KiCad's: a running Altium is **never** closed; `restartNeeded` mirrors `altiumRunning`; capture is skipped with `proofSkipped` when Altium was already open. Sample end-to-end run: LAN7800 bundle → both libs registered in Installed Libraries + a real PCB-Library-editor proof frame.++## What we need from you++1. **ab core (issue adom/adom-bridge#964):** admit `altium_install_library_bundle` through the web consent gate, same dialog as the KiCad/Fusion lanes. `write_file`/`write_file_chunk` staging is already generic.+2. **webcontrol.js:** generalize `installLibraryBundle` (your `Le`) to take the verb name — or add an `eda:'altium'` branch — and add `altium → "Altium"` to the EDA label map so the toggle row shows all three.+3. **Component pages:** emit the Altium action when a page carries an Altium bundle (adom-lbr already writes `.SchLib`/`.PcbLib`).++## Acceptance test++`docs/webcontrol-altium-test.html` on this repo — open it, click **Add to Altium library**. Today it reports `web_forbidden` (proving the gate); the moment #964 lands it stages the LAN7800 bundle and renders the proof frame. Nothing else to set up: it loads YOUR live `static/webcontrol.js` and uses `AdomWebControl.run` directly, so it also regression-tests your handshake path.
docs/webcontrol-altium-test.htmladded+62
@@ -0,0 +1,62 @@+<!doctype html><html><head><meta charset="utf-8"><title>Altium web-control test</title>+<style>+body{font:14px system-ui;background:#0d1117;color:#e6edf3;max-width:760px;margin:40px auto;padding:0 16px}+h1{font-size:20px} code{background:#161b22;padding:2px 5px;border-radius:4px}+.row{display:flex;gap:10px;align-items:center;margin:14px 0}+button{background:#238636;color:#fff;border:0;border-radius:6px;padding:9px 18px;font-size:14px;cursor:pointer}+button:disabled{opacity:.5}+#log{background:#161b22;border:1px solid #30363d;border-radius:8px;padding:12px;white-space:pre-wrap;font:12px ui-monospace,monospace;min-height:120px}+#proof{max-width:100%;border:1px solid #30363d;border-radius:8px;margin-top:12px;display:none}+.dot{width:10px;height:10px;border-radius:50%;background:#6e7681;display:inline-block}+.dot.up{background:#3fb950}.dot.warn{background:#d29922}.dot.down{background:#f85149}+</style></head><body>+<h1>Altium web-control acceptance test</h1>+<p>Mirrors <code>AdomWebControl.installLibraryBundle</code> for the <b>altium</b> bridge: detect ab →+fetch a bundle → stage via <code>write_file_chunk</code> → call+<code>altium_install_library_bundle</code> → render the proof frame. Goes <b>green</b> the moment+ab admits the verb through the web consent gate (adom/adom-bridge issue <b>#964</b>);+until then the expected result is <code>web_forbidden</code>, which proves the gate, not a bug here.</p>+<div class="row"><span id="dot" class="dot"></span><span id="st">Checking for Adom Bridge…</span></div>+<div class="row">+  <label>Bundle URL: <input id="zip" size="52" value="https://wiki.adom.inc/download/adom/altium-bridge/LAN7800-bundle.zip"></label>+  <label>Library: <input id="lib" size="10" value="LAN7800"></label>+</div>+<div class="row"><button id="go" disabled>Add to Altium library</button></div>+<div id="log">—</div>+<img id="proof" alt="proof frame">+<script src="https://wiki.adom.inc/static/webcontrol.js"></script>+<script>+const $=id=>document.getElementById(id), log=m=>{$('log').textContent+='\n'+m};+const W=window.AdomWebControl;+function say(m){log('· '+m)}+W.detect().then(s=>{+  $('dot').className='dot '+(s.ready?'up':s.running?'warn':'down');+  $('st').textContent=s.ready?('Adom Bridge connected'+(s.machine?' on '+s.machine:'')):+    s.running?'ab running, web control off (enable in ab Settings)':'ab not detected';+  $('go').disabled=!s.running;+  $('log').textContent='detect: '+JSON.stringify({running:s.running,ready:s.ready,port:s.port});+});+$('go').onclick=async()=>{+  $('go').disabled=true;$('proof').style.display='none';+  try{+    // identical to webcontrol.js Le(), with the altium verb+    log('fetching bundle…');+    const buf=await fetch($('zip').value,{credentials:'same-origin'}).then(r=>{if(!r.ok)throw new Error('bundle fetch '+r.status);return r.arrayBuffer()});+    log('staging '+buf.byteLength+' bytes via write_file (approve in ab)…');+    const b64=btoa(new Uint8Array(buf).reduce((a,b)=>a+String.fromCharCode(b),''));+    const st=await W.run('write_file',{path:'~/adom-wiki-libs/'+$('lib').value+'.zip',content:b64,encoding:'base64'});+    if(!st.ok)throw Object.assign(new Error(st.error),{code:st.code});+    const staged=(st.data&&st.data.path)||('~/adom-wiki-libs/'+$('lib').value+'.zip');+    log('staged: '+staged+'\ninstalling into Altium…');+    const r=await W.run('altium_install_library_bundle',{zipPath:staged,libraryName:$('lib').value,capture:true,captureMaxWidth:480});+    if(!r.ok)throw Object.assign(new Error(r.error),{code:r.code});+    const d=r.data||{};+    log('RESULT: '+JSON.stringify({success:d.success,symbols:d.symbols,footprints:d.footprints,installed:d.installed,restartNeeded:d.restartNeeded,proofSkipped:d.proofSkipped}));+    if(d.restartNeeded)log('Altium is open — it needs a restart to see the new library (the verb never closes it).');+    if(d.thumbnailDataUrl){$('proof').src=d.thumbnailDataUrl;$('proof').style.display='block';log('proof frame rendered ✓')}+  }catch(e){+    log('BLOCKED/FAILED: '+(e.code||'')+' '+e.message++      (e.code==='web_forbidden'?'\n→ expected until #964 lands: altium_install_library_bundle is not yet on ab\'s web consent allowlist.':''));+  }finally{$('go').disabled=false}+};+</script></body></html>