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.11: detect globalinstall Fusion + notify-on-active-step
8 files changed
+78−31
BRIDGE_VERSION+1−1@@ -1 +1 @@-1.6.10+1.6.11
CHANGELOG.md+15@@ -3,6 +3,21 @@ All notable changes to the Adom Desktop Fusion 360 bridge, newest first. Canonical: https://wiki.adom.inc/adom/adom-desktop-fusion-bridge · GitHub backup: `adom-inc/adom-desktop-fusion-bridge` +## 1.6.11 - 2026-07-03++- **Detect a system-wide (`--globalinstall`) Fusion, not just per-user (fixes a broken onboarding+ loop, found on the ADOMBASELINE fresh-VM test).** The fusion-onboarding skill installs Fusion with+ `--globalinstall`, which lands the launcher under `%ProgramFiles%\Autodesk\webdeploy\production\`,+ but detection (both `fusion_detect.py` and the `bridge.json` `detect` block) only checked+ `%LOCALAPPDATA%`. So an AI-installed Fusion was INVISIBLE - onboarding "succeeded" yet the bridge ++ AD `bridge_readiness` still reported `no-app`. Detection now scans `%LOCALAPPDATA%`, `%ProgramFiles%`,+ `%ProgramFiles(x86)%` (and `%ProgramW6432%`), preferring a complete install (has `.ini`) + newest.+- **Notify the user on EVERY active step.** Per the "the AI does everything, but pull the user in when+ only they can act" rule: the USER skill's convention 4 and fusion-onboarding now mandate an AD+ `notify_user` toast the instant the user must do something (Autodesk sign-in, 2FA, a UAC/elevation+ prompt, license acceptance), and a progress toast for long installs - never silently wait on a+ screen they aren't watching.+ ## 1.6.10 - 2026-07-03 - **"Fusion not installed" hints now honor the SDK Tier-2 cardinal rule (found on a fresh-AD test).**
SKILL.md+1−1@@ -35,7 +35,7 @@ Branch on the stable `errorCode`, never the prose: 1. **Poll readiness, don't launch blindly.** `fusion_readiness` (or AD's `bridge_readiness`) is read-only — it reports `installed`/`running`/`ready`/`addinStale` WITHOUT launching anything. Loop: readiness → act on the row above → drive. 2. **`fusion_readiness` is the standardized cold-start probe.** (Fusion is a detected HOST APP with no heavy download, so there's no `prewarm` step — readiness is the whole gate.) 3. **Core verbs live in the table below; `fusion_describe '{}'` is the full machine-readable catalog.** Read the table to act fast; hit `describe` for completeness — don't guess a verb.-4. **Background by default — don't disrupt the user.** This bridge drives the AI's workspace, not the user's screen. Dismiss dialogs in the BACKGROUND (`fusion_close_window`, never `fusion_send_key`/Escape, which steals focus); only foreground to SHOW the user something. See [fusion-driving](skills/fusion-driving/SKILL.md).+4. **Background by default — but NOTIFY on every active step.** This bridge drives the AI's workspace, not the user's screen: dismiss dialogs in the BACKGROUND (`fusion_close_window`, never `fusion_send_key`/Escape, which steals focus). **The instant the user must DO something you can't (Autodesk sign-in, 2FA, a UAC/elevation prompt, accepting a license, a manual choice), fire an AD `notify_user` (a toast, and a progress toast for long installs) so they're pulled in — never silently wait on a screen they aren't looking at.** Only foreground Fusion to SHOW the user something. See [fusion-driving](skills/fusion-driving/SKILL.md) and [fusion-onboarding](skills/fusion-onboarding/SKILL.md). 5. **`ok:true` is not enough — verify.** A long op that "times out" at ~60s is usually STILL RUNNING server-side (the relay caps the request, not the work). Verify by artifacts (the saved file / a screenshot / `fusion_get_app_state`), don't blindly retry. 6. **Reuse the running Fusion, don't relaunch.** Fusion is a singleton — `fusion_readiness` before `fusion_start` (especially after a compaction); if it's already `ready`, just drive. Relaunching churns state. 7. **Surface `_hint` verbatim + branch on `errorCode`.** Every verb returns an actionable `_hint`; relay it to the user unchanged and key your logic off the stable `errorCode`, not the prose.
adom-bridge-fusion-manifest.json+5−5@@ -1,13 +1,13 @@ { "manifest_version": 1, "name": "fusion360",- "version": "1.6.10",- "url": "https://wiki.adom.inc/download/adom/adom-desktop-fusion-bridge/1.6.10/adom-bridge-fusion-v1.6.10.zip",- "sha256": "a70072e14337eeffd759f33dd83cc93ef37a797136ede1145633cb51013fa461",- "size": 298417,+ "version": "1.6.11",+ "url": "https://wiki.adom.inc/download/adom/adom-desktop-fusion-bridge/1.6.11/adom-bridge-fusion-v1.6.11.zip",+ "sha256": "c9d494cbf710ac86be6bb9bd851fc2cba38ba088d8adf8a910995d50a350aa40",+ "size": 299827, "verbPrefixes": [ "fusion_" ], "healthEndpoint": "/status",- "released_at": "2026-07-03T15:30:00Z"+ "released_at": "2026-07-03T16:15:00Z" }
bridge.json+4−2@@ -2,7 +2,7 @@ "manifest_version": 1, "name": "fusion360", "displayName": "Autodesk Fusion 360",- "version": "1.6.10",+ "version": "1.6.11", "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.",@@ -112,7 +112,9 @@ "hostApp": "Fusion 360", "paths": { "windows": [- "%LOCALAPPDATA%\\Autodesk\\webdeploy\\production\\*\\FusionLauncher.exe"+ "%LOCALAPPDATA%\\Autodesk\\webdeploy\\production\\*\\FusionLauncher.exe",+ "%ProgramFiles%\\Autodesk\\webdeploy\\production\\*\\FusionLauncher.exe",+ "%ProgramFiles(x86)%\\Autodesk\\webdeploy\\production\\*\\FusionLauncher.exe" ], "macos": [ "/Applications/Autodesk Fusion.app",
fusion_detect.py+43−21@@ -13,8 +13,23 @@ from pathlib import Path ADDIN_PORT = 8774 # Fusion 360 uses a web-deploy model — the launcher lives under-# %LOCALAPPDATA%\Autodesk\webdeploy\production\<hash>\FusionLauncher.exe-WEBDEPLOY_BASE = Path(os.environ.get("LOCALAPPDATA", "")) / "Autodesk" / "webdeploy" / "production"+# <base>\Autodesk\webdeploy\production\<hash>\FusionLauncher.exe+# where <base> is %LOCALAPPDATA% for a per-user install OR %ProgramFiles%+# (/%ProgramFiles(x86)%/%ProgramW6432%) for a SYSTEM-WIDE `--globalinstall` -+# which is exactly what the fusion-onboarding skill runs. We MUST check both, or+# an AI-installed (globalinstall) Fusion is invisible and onboarding "succeeds"+# yet the bridge still reports not-installed. (Found on the ADOMBASELINE test.)+_WEBDEPLOY_BASES = []+for _var in ("LOCALAPPDATA", "ProgramFiles", "ProgramFiles(x86)", "ProgramW6432"):+ _root = os.environ.get(_var)+ if _root:+ _base = Path(_root) / "Autodesk" / "webdeploy" / "production"+ if _base not in _WEBDEPLOY_BASES:+ _WEBDEPLOY_BASES.append(_base)+# Back-compat alias (some callers import WEBDEPLOY_BASE directly).+WEBDEPLOY_BASE = _WEBDEPLOY_BASES[0] if _WEBDEPLOY_BASES else (+ Path(os.environ.get("LOCALAPPDATA", "")) / "Autodesk" / "webdeploy" / "production"+) # Add-ins can live in either of these directories (varies by Fusion version) ADDINS_DIR_CANDIDATES = [@@ -59,29 +74,36 @@ def detect_fusion() -> dict: def _find_fusion_launcher() -> Path | None:- """Find FusionLauncher.exe under the webdeploy production directory.+ """Find the newest FusionLauncher.exe across ALL webdeploy bases. - Scans subdirectories sorted by modification time (newest first).+ Checks the per-user (%LOCALAPPDATA%) AND the system-wide (%ProgramFiles%,+ from `--globalinstall`) locations. Prefers a COMPLETE install (one that also+ has FusionLauncher.exe.ini) and, among those, the newest by mtime. """- if not WEBDEPLOY_BASE.exists():- return None+ candidates = [] # (has_ini, mtime, launcher_path)+ 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:+ launcher = subdir / "FusionLauncher.exe"+ if not launcher.exists():+ continue+ has_ini = (subdir / "FusionLauncher.exe.ini").exists()+ try:+ mtime = subdir.stat().st_mtime+ except OSError:+ mtime = 0.0+ candidates.append((has_ini, mtime, launcher)) - try:- subdirs = sorted(- [d for d in WEBDEPLOY_BASE.iterdir() if d.is_dir()],- key=lambda d: d.stat().st_mtime,- reverse=True,- )- except OSError:+ if not candidates: return None-- for subdir in subdirs:- launcher = subdir / "FusionLauncher.exe"- ini_file = subdir / "FusionLauncher.exe.ini"- if launcher.exists() and ini_file.exists():- return launcher-- 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] def _find_addins_dir() -> Path | None:
page.json+1−1@@ -1,6 +1,6 @@ { "slug": "adom-desktop-fusion-bridge",- "version": "1.6.11",+ "version": "1.6.12", "type": "app", "description": "Drive Autodesk Fusion 360 from the cloud via Adom Desktop: 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 with browse/recent/versions, cloud download/upload and folder creation, and in-app parametric modeling. Never-charge: APS calls are capped to the free tier.", "dependencies": {},
skills/fusion-onboarding/SKILL.md+8@@ -57,6 +57,14 @@ shell_execute {"command":"curl -L -o C:\\tmp\\FusionDL.exe \"https://dl.appstrea account** (free) — and Fusion offers a **free trial / personal-use** tier that's enough for viewing and a lot of work. Don't auto-enter their password; do drive the OTP/forms. +> **NOTIFY the user the moment login is needed.** The sign-in (and any 2FA/password step you must+> not auto-fill) is an ACTIVE step only they can do. Fire an AD **`notify_user`** toast ("Fusion is+> installed and open - it needs your Autodesk sign-in to continue") the instant the login screen is+> up, so they act instead of you silently waiting on a screen they aren't watching. Same for the+> `--globalinstall` UAC/elevation prompt (Step 2) and license acceptance. Long installs: use a+> **progress** toast. This is the general rule (see the USER skill's convention 4): notify on EVERY+> step that needs the user.+ ## Step 4 — Complete the circuit: auto-install the AdomBridge add-in This is what lets the bridge inject commands into Fusion after launch. - **The bridge does this for you:** on first dispatch, `server.py` auto-runs `install_addin` if