← Commit history

v1.9.36: recursive coordMap

John Lauer ·2e653c079d · ·parent 9048c8b
4 files changed +36−10
BRIDGE_VERSION+1−1
@@ -1 +1 @@-1.9.35\ No newline at end of file+1.9.36\ No newline at end of file
adom-bridge-fusion-manifest.json+4−4
@@ -1,10 +1,10 @@ {     "manifest_version": 1,     "name": "fusion360",-    "version": "1.9.35",-    "url": "https://wiki.adom.inc/download/adom/fusion-bridge/1.9.35/adom-bridge-fusion-v1.9.35.zip",-    "sha256": "081b01b18ad4946e098e796f1641507ae40aad25239573072a425f477fa2ba84",-    "size": 383740,+    "version": "1.9.36",+    "url": "https://wiki.adom.inc/download/adom/fusion-bridge/1.9.36/adom-bridge-fusion-v1.9.36.zip",+    "sha256": "e9c44a4aef4179d46bda5ace301990e4bb343cddd8214ffa37bf7e27363999e1",+    "size": 384038,     "verbPrefixes": [         "fusion_"     ],
bridge.json+1−1
@@ -2,7 +2,7 @@   "manifest_version": 1,   "name": "fusion360",   "displayName": "Autodesk Fusion 360",-  "version": "1.9.35",+  "version": "1.9.36",   "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.",
server.py+30−4
@@ -4951,6 +4951,32 @@ def _unwrap(r):     return r  +def _find_coordmap(obj, depth=0):+    """Recursively find a coordMap (with shotId) anywhere in a verb response - ab has+    moved it across envelope levels between versions (top-level sibling of data in some,+    nested under data in others, stringified inside output in 2.0.46's direct API).+    Returns the coordMap dict or {}."""+    if depth > 5:+        return {}+    if isinstance(obj, str) and obj[:1] in "[{":+        try:+            import json as _j+            return _find_coordmap(_j.loads(obj), depth + 1)+        except Exception:+            return {}+    if isinstance(obj, dict):+        cm = obj.get("coordMap")+        if isinstance(cm, dict) and cm.get("shotId"):+            return cm+        if obj.get("shotId"):+            return obj+        for k in ("data", "output", "result", "response"):+            got = _find_coordmap(obj.get(k), depth + 1)+            if got:+                return got+    return {}++ def _fusion_click_signin() -> dict:     """Click Fusion's 'Welcome to Fusion' -> Sign In button SERVER-SIDE, ALWAYS, on the user's     behalf (John, 2026-07-22: "you should ALWAYS just click sign in on behalf of the adom@@ -4975,10 +5001,10 @@ def _fusion_click_signin() -> dict:      _raw = _ad_call("desktop_screenshot_window", {"hwnd": int(hwnd)}, timeout=45)     shot = _unwrap(_raw)-    # coordMap lives at the TOP level of the response, BESIDE data - _unwrap alone loses it-    # (this exact miss broke the server-side Sign In click twice, 2026-08-16).-    cm = shot.get("coordMap") or (_raw.get("coordMap") if isinstance(_raw, dict) else None) or {}-    sid = cm.get("shotId") or shot.get("shotId") or (_raw.get("shotId") if isinstance(_raw, dict) else None)+    # ab has moved coordMap across envelope levels between versions (sibling of data /+    # nested / stringified in output on 2.0.46) - search recursively, never guess a level.+    cm = _find_coordmap(_raw)+    sid = cm.get("shotId")     if not sid:         return {"clicked": False,                 "why": "screenshot returned no shotId (hwnd=%s raw_keys=%s err=%s)" % (