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.67: notify reach_user uses target=all (peers() broke on 'targets'->'clients' shape drift, so a VM toast hit only itself); recognize broadcast summary as success + report reached desktops; peers() tolerant of clients shape
5 files changed
+30−21
BRIDGE_VERSION+1−1@@ -1 +1 @@-1.6.66+1.6.67
ad_client.py+10−3@@ -239,13 +239,16 @@ def self_name(): def peers(): """clientNames of the OTHER ADs on the relay (excludes self). [] if none/unknown.""" res = call("targets") or {}- tlist = res.get("targets") if isinstance(res, dict) else None+ # tolerate shape drift: the peer list is under `clients` on current AD, `targets` on older.+ tlist = None+ if isinstance(res, dict):+ tlist = res.get("targets") or res.get("clients") if not isinstance(tlist, list): return [] me = self_name() out = [] for t in tlist:- n = (t or {}).get("name") or (t or {}).get("hostname")+ n = t if isinstance(t, str) else ((t or {}).get("name") or (t or {}).get("hostname") or (t or {}).get("clientName")) if n and n != me: out.append(n) return out@@ -267,7 +270,11 @@ def notify(title, body, level="info", buttons=None, target=None, reach_user=Fals if buttons: args["buttons"] = buttons tgt = target- if tgt is None and reach_user and peers():+ if tgt is None and reach_user:+ # Fan out to EVERY connected desktop so the toast lands wherever the user actually is. Do NOT+ # gate on peers() (John 2026-07-14): the `targets` response shape drifted to {clients:[...]}+ # so peers() wrongly returns [] and the toast would hit only THIS (unattended VM). The relay+ # honors target="all" directly - verified reaching the user's laptop. tgt = "all" res = call("notify_user", args, target=tgt) return res
adom-bridge-fusion-manifest.json+4−4@@ -1,10 +1,10 @@ { "manifest_version": 1, "name": "fusion360",- "version": "1.6.66",- "url": "https://wiki.adom.inc/download/adom/adom-desktop-fusion-bridge/1.6.66/adom-bridge-fusion-v1.6.66.zip",- "sha256": "64833c2f7d513837e4a70b86f2de3939c57c7dee06b5ad46f2a326c03869e479",- "size": 360022,+ "version": "1.6.67",+ "url": "https://wiki.adom.inc/download/adom/adom-desktop-fusion-bridge/1.6.67/adom-bridge-fusion-v1.6.67.zip",+ "sha256": "1d5c3a7ff010fd90b8ad995c51fc2fa930140890b12be6624dfe56246ed80c14",+ "size": 360402, "verbPrefixes": [ "fusion_" ],
bridge.json+1−1@@ -2,7 +2,7 @@ "manifest_version": 1, "name": "fusion360", "displayName": "Autodesk Fusion 360",- "version": "1.6.66",+ "version": "1.6.67", "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.",
server.py+14−12@@ -282,20 +282,22 @@ def _handle_notify_owner(args: dict) -> dict: "_hint": ("Relay the notifyUser payload yourself: `adom-desktop --target all notify_user " "{title, body, level}` (or `--target <the user's host>`)."), }- peers = []- try:- peers = ad_client.peers()- except Exception:- pass- res = ad_client.notify(title, body, level=level, reach_user=True)- ok = bool(res and (res.get("success") or res.get("status") == "ok"))+ res = ad_client.notify(title, body, level=level, reach_user=True) or {}+ # reach_user fans out via target="all", whose response is a BROADCAST envelope+ # {results:{host:{action}}, summary:{ok,failed,total}, targets:[...]}. Recognize that shape for+ # success (summary.ok>0) - not just the single-target {status:"ok"} - and report the ACTUAL+ # desktops reached, so a toast that landed on the user's laptop isn't mis-reported as failed.+ summary = res.get("summary") or {}+ ok = bool(res.get("success") or res.get("status") == "ok" or summary.get("ok", 0) > 0)+ reached = res.get("targets") or (["self"] if ok else []) return { "success": ok,- "targets": (["self"] + peers) if peers else ["self"],- "_hint": ("Toast sent" + (" to this machine AND all peer ADs (user may be on another computer)."- if peers else " to this machine (no peer ADs on the relay).")- + " This is the LAST RESORT - only use after exhausting programmatic options "- "(UIA background clicks, seat auto-resolve, warm-SSO sign-in). Now WAIT and poll "+ "via": "ad_client:direct(all)",+ "targets": reached,+ "_hint": ("Toast fanned out to ALL connected desktops (the user's machine included) via the "+ "in-process AD direct API. This is the LAST RESORT - only use after exhausting "+ "programmatic options (UIA background clicks, seat auto-resolve, warm-SSO sign-in), "+ "and only when the box is ACTUALLY ready for the user to act. Now WAIT and poll " "fusion_readiness for the state to clear; do not re-toast within a few minutes."), }