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
v1.6.59: bake fresh-install completeness guard (readiness) + launch-error dialog detection & webdeploy auto-clean (fusion_detect) so a mid-stream FusionLauncher never triggers Error Launching Streamed Application
5 files changed
+98−13
BRIDGE_VERSION+1−1@@ -1 +1 @@-1.6.58+1.6.59
adom-bridge-fusion-manifest.json+4−4@@ -1,10 +1,10 @@ { "manifest_version": 1, "name": "fusion360",- "version": "1.6.58",- "url": "https://wiki.adom.inc/download/adom/adom-desktop-fusion-bridge/1.6.58/adom-bridge-fusion-v1.6.58.zip",- "sha256": "d528bad4a61f7adab8a15a77eaaa4c197e263ee392cb43b5d627a98943a3c0a9",- "size": 347717,+ "version": "1.6.59",+ "url": "https://wiki.adom.inc/download/adom/adom-desktop-fusion-bridge/1.6.59/adom-bridge-fusion-v1.6.59.zip",+ "sha256": "a4269760b2aa726a06ec346e3dda78b65db5cd5a87e9055b34c4bbb82ad5140c",+ "size": 349140, "verbPrefixes": [ "fusion_" ],
bridge.json+2−2@@ -2,7 +2,7 @@ "manifest_version": 1, "name": "fusion360", "displayName": "Autodesk Fusion 360",- "version": "1.6.58",+ "version": "1.6.59", "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/adom-desktop-fusion-bridge", "author": "Adom Inc.",@@ -181,4 +181,4 @@ } ] }-}+}
fusion_detect.py+74−3@@ -107,9 +107,52 @@ def _find_fusion_launcher() -> Path | None: if not candidates: return None- # Complete installs (has_ini) win; newest mtime breaks ties.- candidates.sort(key=lambda c: (c[0], c[1]), reverse=True)- return candidates[0][2]+ # Only a COMPLETE install (FusionLauncher.exe.ini present) counts as installed. A hash dir with+ # FusionLauncher.exe but NO .ini is a half-streamed/corrupt install - returning it made+ # detect_fusion() report installed:true mid-stream, so a fusion_start fired into it and hit+ # "Error Launching Streamed Application ... .ini is missing or incomplete" (fresh Hyper-V VM,+ # John, 2026-07-14). If nothing is complete, report NOT installed (readiness then surfaces the+ # streamer as installing).+ complete = [c for c in candidates if c[0]]+ if complete:+ complete.sort(key=lambda c: c[1], reverse=True) # newest complete install wins+ return complete[0][2]+ return None+++_MIN_VALID_INI_BYTES = 512 # the truncated launcher .ini that broke the fresh VM was 412 bytes+++def _clean_incomplete_webdeploy() -> list:+ """Remove webdeploy production hash dirs that are INCOMPLETE: a FusionLauncher.exe present but its+ FusionLauncher.exe.ini missing or truncated (< _MIN_VALID_INI_BYTES). These are the residue of an+ interrupted stream that throws 'Error Launching Streamed Application'. Only ever called AFTER a+ launch failure (we already know something is corrupt), so aggressive cleanup is safe. Returns the+ dir names removed. Never raises."""+ import shutil+ removed = []+ for base in _WEBDEPLOY_BASES:+ if not base.exists():+ continue+ try:+ subdirs = [d for d in base.iterdir() if d.is_dir()]+ except OSError:+ continue+ for subdir in subdirs:+ if not (subdir / "FusionLauncher.exe").exists():+ continue+ ini = subdir / "FusionLauncher.exe.ini"+ try:+ ok = ini.exists() and ini.stat().st_size >= _MIN_VALID_INI_BYTES+ except OSError:+ ok = False+ if not ok:+ try:+ shutil.rmtree(subdir, ignore_errors=True)+ removed.append(subdir.name)+ except Exception:+ pass+ return removed def fusion_update_in_progress() -> bool:@@ -679,6 +722,34 @@ def ensure_fusion_running(fusion_info: dict, wait_addin: bool = False) -> dict | if _has_fusion_process(): break else:+ # LAUNCH FAILED - do NOT return a blind "process not found". READ the dialog that is almost+ # certainly on screen. The classic fresh-box cause is an INCOMPLETE stream: "Error Launching+ # Streamed Application ... FusionLauncher.exe.ini is missing or incomplete" (John, live on a+ # fresh Hyper-V VM 2026-07-14). Detect + dismiss it, CLEAN the corrupt webdeploy dir(s), and+ # tell the caller to re-stream - instead of silently sitting on a broken install.+ launch_err = None+ try:+ from handlers.dialog_classify import classify_launch_dialogs, close_dialog_bg+ for d in classify_launch_dialogs():+ if d.get("category") == "launch_error" or "streamed application" in (d.get("title") or "").lower():+ launch_err = d+ close_dialog_bg(d.get("hwnd"))+ except Exception:+ pass+ removed = _clean_incomplete_webdeploy()+ if launch_err or removed:+ return {+ "success": False,+ "error": "Fusion launch failed: INCOMPLETE streamed install (FusionLauncher.exe.ini "+ "missing or truncated).",+ "errorCode": "fusion_incomplete_install",+ "cleanedWebdeployDirs": removed,+ "dialog": (launch_err or {}).get("title"),+ "_hint": "AUTO-RECOVERED: dismissed the launch-error dialog and removed the corrupt "+ "webdeploy dir(s). Re-run fusion_install_fusion, then WAIT for fusion_readiness "+ "to report installing:false (the streamer has exited) BEFORE fusion_start - "+ "starting mid-stream is what corrupts the install.",+ } return { "success": False, "error": "Fusion 360 launched but process not found after 30s",
server.py+17−3@@ -1135,9 +1135,23 @@ def _handle_fusion_readiness(fusion_info: dict, args: dict) -> dict: # report installed/running/ready:true on a machine where Fusion had been removed # (found live on a fresh VM 2026-07-05: NO_WEBDEPLOY on disk, yet readiness said # ready). detect_fusion() is a fast filesystem scan, so pay it every call.- installed = bool(detect_fusion().get("installed"))- running = _is_fusion_running() if installed else False- installing = (not installed) and _installer_running()+ raw_installed = bool(detect_fusion().get("installed"))+ streaming = _installer_running()+ running = _is_fusion_running() if raw_installed else False+ # FRESH-INSTALL COMPLETENESS GUARD (John caught this live 2026-07-14 on a fresh Hyper-V VM):+ # the streamer writes FusionLauncher.exe BEFORE it finishes writing FusionLauncher.exe.ini, so+ # detect_fusion() flips installed:true mid-stream. Starting into that half-written install throws+ # "Error Launching Streamed Application ... FusionLauncher.exe.ini is missing or incomplete" and+ # leaves TWO corrupt webdeploy production dirs. So: while the streamer is running and Fusion is+ # NOT already up (i.e. this is a first install, not a background auto-update of a running Fusion),+ # the install is STILL STREAMING - report installed:false + installing:true so nothing calls+ # fusion_start yet. Only treat it as installed once the streamer has exited.+ if streaming and not running:+ installed = False+ installing = True+ else:+ installed = raw_installed+ installing = (not installed) and streaming # The add-in only serves once Fusion is PAST sign-in (its HTTP server runs on # Fusion's main thread, which the sign-in modal blocks). So a responding add-in