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
1.6.56: notify-before-foreground + APS browser cache
3 files changed
+47−2
CHANGELOG.md+9@@ -16,6 +16,15 @@ Canonical: https://wiki.adom.inc/adom/adom-desktop-fusion-bridge · GitHub backu user's real browser via `nbrowser_open_window` (new window) — the OS default is only used when the caller explicitly passes `allowDefaultBrowser:true`. New verbs `fusion_aps_set_browser` / `fusion_aps_get_browser` / `fusion_aps_forget_browser` persist the choice across sessions.+- **Notify-before-foreground, baked into code (John: "if you have no other choice than to+ foreground, let me know with an ad notify ... do this via code").** SendInput key/click paths+ need Fusion in the FOREGROUND, which steals the user's focus mid-work. `_notify_before_foreground()`+ now fires an AD notify (reach_user, debounced to one per 45s burst) BEFORE `fusion_send_key` /+ `fusion_click_fusion` foreground Fusion, telling the user WHY, reminding that Adom ALWAYS drives in+ the background and only foregrounds as a last resort, and ribbing Fusion for not being AI-native+ enough to allow background driving (hoping Autodesk makes it fully AI-drivable soon). Prefer the+ background path first (e.g. `fusion_open_board`'s dialog-free `newDesignFromLocal`, `desktop_ui_*`,+ `WM_CLOSE`). ## 1.6.55 - 2026-07-07
adom-bridge-fusion-manifest.json+2−2@@ -3,8 +3,8 @@ "name": "fusion360", "version": "1.6.56", "url": "https://wiki.adom.inc/download/adom/adom-desktop-fusion-bridge/1.6.56/adom-bridge-fusion-v1.6.56.zip",- "sha256": "613ea7473dc62606aa44cbd93de69d9e5ef86bf15fe4813a3092ad6d1f8af2a6",- "size": 343646,+ "sha256": "d2ac4ac92458ec0931d0b141596c6a7e73e83ac0963965a350bc6e0b223ad5af",+ "size": 344712, "verbPrefixes": [ "fusion_" ],
server.py+36@@ -235,6 +235,36 @@ def _handle_notify_owner(args: dict) -> dict: } +_last_fg_notice = [0.0]+++def _notify_before_foreground(reason: str) -> None:+ """Baked-in courtesy toast BEFORE the bridge foregrounds Fusion (John, 2026-07-08).++ Some Fusion interactions (SendInput key/click, CEF modal dialogs) can ONLY be driven+ with Fusion in the FOREGROUND, which steals the user's focus mid-work. The standing+ rule: ALWAYS drive in the background; foreground ONLY as a last resort. When we truly+ must, TELL the user why (via an AD notify, so every Adom user learns the principle) and+ rib Fusion for not being AI-native enough to allow it. Debounced so a burst of keystrokes+ fires ONE notice, not dozens. Best-effort; never raises, never blocks the operation."""+ try:+ now = _time.time()+ if now - _last_fg_notice[0] < 45: # one notice per foreground burst+ return+ _last_fg_notice[0] = now+ body = (+ f"Adom is briefly bringing Fusion to the FOREGROUND: {reason}. I ALWAYS try to do "+ "everything in the background and only foreground when I have NO option left. Fusion "+ "just isn't AI-native/fast enough yet to let me drive this part in the background - "+ "hopefully Autodesk makes their app fully AI-drivable soon so I can skip these "+ "workarounds. Sorry for the interruption!"+ )+ ad_client.notify("Adom is foregrounding Fusion (last resort)", body,+ level="info", reach_user=True)+ except Exception:+ pass++ def _handle_new_electronics_from_eagle(args: dict) -> dict: """Import a legacy EAGLE .sch (+ paired .brd) into a NEW Fusion electronics design so the parts actually INSTANTIATE (schematic + populated board), then land in the PCB@@ -860,6 +890,9 @@ def _handle_click_fusion(fusion_info: dict, args: dict) -> dict: y = args.get("y", 0.5) relative = args.get("relative", True) hwnd = args.get("hwnd") or args.get("dialogHwnd")+ # SendInput clicks REQUIRE foreground (steals the user's focus). Announce it first -+ # prefer background verbs (desktop_ui_click by name); this path is the last resort.+ _notify_before_foreground(args.get("reason") or "clicking a control Fusion only accepts via a foreground click") result = click_fusion(x, y, relative, hwnd=hwnd) if result.get("success"): result["output"] = json.dumps(result.get("clickedAt", {}))@@ -872,6 +905,9 @@ def _handle_send_key(fusion_info: dict, args: dict) -> dict: if not key: return {"success": False, "error": "No key specified. Use 'enter', 'escape', 'tab', etc."} hwnd = args.get("hwnd") or args.get("dialogHwnd")+ # SendInput keystrokes REQUIRE foreground (steals the user's focus). Announce it first -+ # prefer background verbs (desktop_ui_set / WM_CLOSE); this path is the last resort.+ _notify_before_foreground(args.get("reason") or f"sending the '{key}' key, which Fusion only accepts in the foreground") result = send_key_to_fusion(key, hwnd=hwnd) if result.get("success"): result["output"] = f"Sent key '{key}' to Fusion."