app
Fusion - the Fusion 360 Bridge
Public Made by Adomby adom
Drive Autodesk Fusion 360 from the cloud via Adom Bridge: component libraries, IPC package generation, board layout, exports (STEP/Gerbers/BOM/CPL), fast APS cloud search, and parametric modeling.
← Commit history
Update 15 file(s)
9 files changed
+54−33
BRIDGE_VERSION+1−1@@ -1 +1 @@-1.9.189+1.9.190
adom-bridge-fusion-manifest.json+4−4@@ -1,10 +1,10 @@ { "manifest_version": 1, "name": "fusion360",- "version": "1.9.189",- "url": "https://wiki.adom.inc/download/adom/fusion-bridge/1.9.189/adom-bridge-fusion-v1.9.189.zip",- "sha256": "1ea7e99d114891d325585c6d39e60ad1049702af3631b3c0f050aa6f9703fa73",- "size": 489374,+ "version": "1.9.190",+ "url": "https://wiki.adom.inc/download/adom/fusion-bridge/1.9.190/adom-bridge-fusion-v1.9.190.zip",+ "sha256": "79028cd19a140949ececc99e9adc7fe6e82cad079180a8d602f8a766d857ceeb",+ "size": 489370, "verbPrefixes": [ "fusion_" ],
bridge.json+1−1@@ -2,7 +2,7 @@ "manifest_version": 1, "name": "fusion360", "displayName": "Autodesk Fusion 360",- "version": "1.9.189",+ "version": "1.9.190", "description": "Drive Autodesk Fusion 360 from the cloud: launch Fusion, electronics board layout, design rules, exports (STEP/IGES/STL/3MF/USDZ/OBJ/DXF/DWG/Gerbers/BOM/CPL), fast APS server-indexed cloud search plus browse/recent/file-info/versions, cloud file download/upload and folder creation, and in-app parametric modeling (fusion_run_modeling_script). Never-charge: APS calls are capped to the free tier.", "homepage": "https://wiki.adom.inc/adom/fusion-bridge", "author": "Adom Inc.",
dashboard/Cargo.lock+1−1@@ -4,7 +4,7 @@ version = 4 [[package]] name = "fusion-dashboard"-version = "1.9.189"+version = "1.9.190" dependencies = [ "serde_json", ]
dashboard/Cargo.toml+1−1@@ -1,6 +1,6 @@ [package] name = "fusion-dashboard"-version = "1.9.189"+version = "1.9.190" edition = "2021" [dependencies]
dashboard/ui/index.html+33−15@@ -136,9 +136,9 @@ dialog:focus,dialog:focus-visible{outline:none} .choice.sel{border-color:var(--accent);box-shadow:inset 0 0 0 1px var(--accent)} .choice:focus-within{outline:2px solid var(--accent);outline-offset:2px} /* House scrollbar for the settings body (never the fat OS bar) */-.dlgbody::-webkit-scrollbar{width:9px}-.dlgbody::-webkit-scrollbar-thumb{background:rgba(139,148,158,.35);border-radius:999px;border:2px solid transparent;background-clip:content-box}-.dlgbody::-webkit-scrollbar-thumb:hover{background:var(--accent);background-clip:content-box}+.dlgbody::-webkit-scrollbar{width:10px}+.dlgbody::-webkit-scrollbar-thumb{background:rgba(139,148,158,.32);border-radius:999px;border:2px solid transparent;background-clip:padding-box}+.dlgbody::-webkit-scrollbar-thumb:hover{background:rgba(0,184,177,.55);background-clip:padding-box} /* Two-click Restore defaults footer */ .settings-footer{margin-top:1.2rem;padding:1rem 18px 16px;border-top:1px solid var(--border);display:flex;flex-direction:column;gap:.5rem} .restore-btn{width:fit-content;display:inline-flex;align-items:center;gap:.4rem;padding:.4rem .85rem;background:transparent;border:1px solid var(--border);border-radius:.375rem;color:var(--text-body);font-family:'Familjen Grotesk',sans-serif;font-size:12.5px;font-weight:600;cursor:pointer;transition:background .15s ease,border-color .15s ease,color .15s ease}@@ -185,8 +185,11 @@ dialog:focus,dialog:focus-visible{outline:none} dialog.settings{max-width:560px;overflow:hidden;padding:0} .dlghead{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:16px 18px 10px} .dlghead h2{margin:0;font-size:17px}-.dlgbody{max-height:70vh;overflow:auto;padding:0 18px 18px}-.dlgbody::-webkit-scrollbar-track{margin:8px 0}+.dlgbody{max-height:70vh;overflow:auto;padding:0 18px 18px;scrollbar-gutter:stable}+/* Track inset >= the dialog's 12px radius (scrollbars sub-skill: the rounded-corner+ slice John caught on THIS modal). The overflow:hidden dialog + inner scroller is the+ structural fix; the margin is belt and suspenders for the top/bottom curve. */+.dlgbody::-webkit-scrollbar-track{margin:12px 0} .xbtn{width:30px;height:30px;display:flex;align-items:center;justify-content:center;background:none;border:1px solid transparent;border-radius:8px;color:var(--text-2);cursor:pointer;font-size:18px;line-height:1;transition:background .15s ease,border-color .15s ease,color .15s ease,transform .06s ease} .xbtn:hover{background:var(--elevated);border-color:var(--border);color:var(--text)} .xbtn:active{transform:scale(.9);background:var(--surface)}@@ -231,7 +234,7 @@ dialog.settings{max-width:560px;overflow:hidden;padding:0} and foremost in those dashboards, possibly even at the top of it." --> <div class="saystrip" id="saystrip"> <div class="saytitle">Say it</div>- <div class="saydesc">You never need this page's buttons: just tell your AI what you want, using the word <b>fusion</b>. Click a phrase to copy it, then paste it to your AI.</div>+ <div class="saydesc">You never need this page's buttons: just tell your AI what you want, using the word <b>fusion</b>. Click a phrase or its <span class="saytry-hint">Try it</span> to copy the prompt, then paste it into any AI thread.</div> <div class="saychips" id="sayChips"></div> </div> @@ -381,11 +384,11 @@ let curTarget=localStorage.getItem('fdTarget')||''; // SAY IT strip (dock-bar `say` contract): keep this list in lockstep with dockbar.json's // `say` array - the dock interstitial and this strip must teach the same phrases.-// SHIP-NIGHT POSTURE (dock-bar thread, 2026-08-23): Try-it is PARKED - the strip is-// COPY-ONLY until the ah AI-threads typing fix is certified (a submit:false probe on a-// d096856+ build; project-a6 broadcasts the all-clear). Rationale: /ai-threads/run-prompt-// has crashed a dev ah deterministically, and any control-API call wakes ah's parked AI-// backend. Flip SAY_TRY_ENABLED back to true when the all-clear lands - the code stays.+// SHIP-NIGHT POSTURE, amended by John's ruling (2026-08-23, via the dock-bar thread):+// NO live AI-thread staging for now - /api/say-try stays PARKED server-side and the+// census staging code below stays dormant (SAY_TRY_ENABLED=false until the fleet+// all-clear). But the Try button is BACK with new behavior: it copies the phrase to the+// clipboard and toasts exactly what happened. Zero /ai-threads calls from page or server. const SAY_TRY_ENABLED=false; const SAY_PHRASES=[ 'open the step in fusion',@@ -396,8 +399,19 @@ const SAY_PHRASES=[ 'export the fusion design as STEP', ]; function copyText(t){- // clipboard API needs a secure context; webviews sometimes lack it - textarea fallback.- if(navigator.clipboard&&navigator.clipboard.writeText)return navigator.clipboard.writeText(t).catch(()=>copyTextLegacy(t));+ // clipboard API needs a secure context AND a focused document: an unfocused window+ // HANGS navigator.clipboard.writeText ("document is not focused") - so check focus+ // SYNCHRONOUSLY and take the in-gesture execCommand path immediately (an execCommand+ // fallback after an async rejection is outside the user gesture and fails too).+ // Focused path still races an ~800ms timeout into the legacy fallback.+ // (parts-search 1.1.2 recipe, dock-bar fleet contract.)+ if(!(document.hasFocus&&document.hasFocus()))return Promise.resolve(copyTextLegacy(t));+ if(navigator.clipboard&&navigator.clipboard.writeText){+ return Promise.race([+ navigator.clipboard.writeText(t),+ new Promise((_,rej)=>setTimeout(()=>rej(new Error('clipboard timeout')),800))+ ]).catch(()=>copyTextLegacy(t));+ } return Promise.resolve(copyTextLegacy(t)); } function copyTextLegacy(t){const ta=document.createElement('textarea');ta.value=t;ta.style.position='fixed';ta.style.opacity='0';document.body.appendChild(ta);ta.select();try{document.execCommand('copy');}catch(e){}ta.remove();}@@ -408,8 +422,12 @@ function copyTextLegacy(t){const ta=document.createElement('textarea');ta.value= const btn=document.createElement('button');btn.className='phrase';btn.textContent=p; btn.setAttribute('data-tip','Copy this phrase - paste it to any AI thread'); btn.onclick=async()=>{await copyText(p);toast('Copied - paste it to your AI','ok');};- if(!SAY_TRY_ENABLED){chip.appendChild(btn);host.appendChild(chip);return;}- const tr=document.createElement('button');tr.className='try';tr.textContent='Try';+ const tr=document.createElement('button');tr.className='try';tr.textContent='Try it';+ if(!SAY_TRY_ENABLED){+ tr.setAttribute('data-tip','Copy this prompt to your clipboard');+ tr.onclick=async()=>{await copyText(p);toast('Copied to clipboard. Paste it into any AI thread.','ok');};+ chip.appendChild(btn);chip.appendChild(tr);host.appendChild(chip);return;+ } tr.setAttribute('data-tip',"Type this phrase into the app's AI thread for you - you press Enter to run it"); tr.onclick=async()=>{ try{
install.sh+1−1@@ -21,7 +21,7 @@ echo "Installed fusion-bridge skills: $(ls "$PKG_DIR/skills" 2>/dev/null | tr '\ # binary (the three-artifact pattern: bridge zip -> ab, THIS pkg -> container skills + # this download, page media -> wiki). Per the wiki's PKG_VS_RELEASE policy, binaries are # platform-tagged RELEASE assets, never tarball content - the installer fetches them.-DASH_VERSION="1.9.189"+DASH_VERSION="1.9.190" DASH_URL="https://wiki.adom.inc/download/adom/fusion-bridge/${DASH_VERSION}/fusion-dashboard" DEST="" if [ -w /usr/local/bin ]; then DEST=/usr/local/bin
package.json+1−1@@ -1,6 +1,6 @@ { "slug": "fusion-bridge",- "version": "1.9.189",+ "version": "1.9.190", "type": "app", "description": "This package installs the bridge's SKILLS into your container so your AI knows how to drive it; Adom Bridge loads the bridge runtime itself from the release zip.", "dependencies": {
page.json+11−8@@ -1,6 +1,6 @@ { "slug": "fusion-bridge",- "version": "1.9.189",+ "version": "1.9.190", "type": "app", "description": "This package installs the bridge's SKILLS into your container so your AI knows how to drive it; Adom Bridge loads the bridge runtime itself from the release zip.", "dependencies": {@@ -11,6 +11,10 @@ "uninstall": "./uninstall.sh" }, "tags": [+ "ab",+ "bridge",+ "fusion",+ "desktop-app", "fusion360", "autodesk", "cad",@@ -75,7 +79,10 @@ "build a basic parts library", "add a 3d model to a component", "make a fusion 360 library with 3d",- "set up the fusion bridge"+ "set up the fusion bridge",+ "fusion dashboard",+ "fusion status page",+ "open the fusion launch page" ], "discovery_pitch": "Use the Adom Bridge Fusion 360 bridge when the user wants to DRIVE Autodesk Fusion 360 from the cloud: open/search their team's Fusion cloud designs, lay out a PCB or do electronics, export STEP/IGES/STL/Gerbers/BOM, or build a component library with real rendering 3D. It runs Fusion on the user's own machine via Adom Bridge. NOT for web/browser/login/form-filling (that's the native-browser extension) and NOT for KiCad (that's the kicad bridge).", "brief": "Drive Autodesk Fusion 360 from the cloud via Adom Bridge: component libraries, IPC package generation, board layout, exports (STEP/Gerbers/BOM/CPL), fast APS cloud search, and parametric modeling.",@@ -104,9 +111,5 @@ "label": "Part volume", "prompt": "How much material does each printed part in this assembly use?" }- ],- "author": {- "name": "John Lauer",- "email": "[email protected]"- }-}+ ]+}