← Commit history

Update 6 file(s)

John Lauer ·797bbc12c6 ·1mo ago ·parent 33a6339
6 files changed +52−17
BRIDGE_VERSION+1−1
@@ -1 +1 @@-1.9.120\ No newline at end of file+1.9.121\ 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.120",-  "url": "https://wiki.adom.inc/download/adom/fusion-bridge/1.9.135/adom-bridge-fusion-v1.9.120.zip",-  "sha256": "f5afdcbab0498fc627f1cbb47a2838230822a52dadd1ce66ffa866cd4e012830",-  "size": 455871,+  "version": "1.9.121",+  "url": "https://wiki.adom.inc/download/adom/fusion-bridge/1.9.136/adom-bridge-fusion-v1.9.121.zip",+  "sha256": "eec4f3ba279d3dd1a6aa349b3df8c8d459541fbe4d7e3a8f7081b19ea819fd3b",+  "size": 456629,   "verbPrefixes": [     "fusion_"   ],
bridge.json+1−1
@@ -2,7 +2,7 @@   "manifest_version": 1,   "name": "fusion360",   "displayName": "Autodesk Fusion 360",-  "version": "1.9.120",+  "version": "1.9.121",   "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.",
package.json+1−1
@@ -1,6 +1,6 @@ {   "slug": "fusion-bridge",-  "version": "1.9.135",+  "version": "1.9.136",   "type": "app",   "description": "This package installs the bridge's SKILLS into your container so your AI knows how to drive it; Adom Bridge loads the bridge runtime itself from the release zip.",   "dependencies": {
page.json+10−7
@@ -1,6 +1,6 @@ {   "slug": "fusion-bridge",-  "version": "1.9.135",+  "version": "1.9.136",   "type": "app",   "description": "This package installs the bridge's SKILLS into your container so your AI knows how to drive it; Adom Bridge loads the bridge runtime itself from the release zip.",   "dependencies": {@@ -11,6 +11,10 @@     "uninstall": "./uninstall.sh"   },   "tags": [+    "ab",+    "bridge",+    "fusion",+    "desktop-app",     "fusion360",     "autodesk",     "cad",@@ -70,7 +74,10 @@     "build a basic parts library",     "add a 3d model to a component",     "make a fusion 360 library with 3d",-    "set up the fusion bridge"+    "set up the fusion bridge",+    "fusion dashboard",+    "fusion status page",+    "open the fusion launch page"   ],   "discovery_pitch": "Use the Adom Bridge Fusion 360 bridge when the user wants to DRIVE Autodesk Fusion 360 from the cloud: open/search their team's Fusion cloud designs, lay out a PCB or do electronics, export STEP/IGES/STL/Gerbers/BOM, or build a component library with real rendering 3D. It runs Fusion on the user's own machine via Adom Bridge. NOT for web/browser/login/form-filling (that's the native-browser extension) and NOT for KiCad (that's the kicad bridge).",   "brief": "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.",@@ -99,9 +106,5 @@       "label": "Part volume",       "prompt": "How much material does each printed part in this assembly use?"     }-  ],-  "author": {-    "name": "John Lauer",-    "email": "[email protected]"-  }+  ] }\ No newline at end of file
server.py+35−3
@@ -7036,8 +7036,26 @@ def _show_library_view(name, suffix, lbr_path=None):         _pending = [d for d in (classify_blocking_dialogs() or [])                     if d.get("category") == "create_confirm"]         if _pending:+            # A create_confirm on screen is not automatically OURS (run 7d4427d443f5: a+            # footprint EDIT whose name WAS in the library got failed because a stale+            # Create-new prompt from an earlier interaction was still standing). Read the+            # dialog's own text: only a prompt that names THIS artifact fails THIS call.+            # Foreign/stale prompts are still declined (never left blocking the main+            # thread), but the EDIT's own outcome decides the result.+            _about_this = False             for _d in _pending:+                try:+                    from handlers.dialog_classify import _dialog_text as _dtxt+                    _body = "%s %s" % (_dtxt(_d.get("hwnd")) or "", _d.get("title") or "")+                except Exception:+                    _body = _d.get("title") or ""+                if str(name).lower() in _body.lower():+                    _about_this = True                 _unwrap(_ad_call("desktop_ui_click", {"hwnd": _d.get("hwnd"), "name": "No"}, timeout=12))+            if not _about_this:+                print("[Fusion Bridge] declined a STALE Create-new prompt that does not mention "+                      "%r - clearing it and trusting the EDIT's own result" % name)+        if _pending and _about_this:             print("[Fusion Bridge] declined a Create-new prompt for %r - the name is not in the "                   "library (answering Yes would fabricate an empty artifact)" % name)             return {@@ -9270,13 +9288,19 @@ def _handle_prove_library(fusion_info: dict, args: dict) -> dict:         # Create3DPackage opens the empty Package3D GENERATOR for an already-bound library -         # bodies=0, a frame of nothing). The evidence is the f3d the package3d urn points         # at: open THAT document, which loads the real geometry the Library Manager shows.+        # THE URN LIVES IN wip_urn, NOT urn (run 7d4427d443f5): this bridge's own bind+        # writes `<package3d urn="" wip_urn="urn:adsk.wipprod:fs.file:vf...">` - urn stays+        # empty by the EAGLE-XML convention used everywhere else in this file. Reading only+        # `urn` made a bound library look unopenable ("no urn"). A caller (the create_library+        # chain) can also hand the bind result's urn straight in as f3dUrn.         _p3d_urn = ""         try:             import xml.etree.ElementTree as _ET3             for _p3 in _ET3.parse(lbr).getroot().iter("package3d"):-                _p3d_urn = (_p3.get("urn") or "").strip() or _p3d_urn+                _p3d_urn = (_p3.get("urn") or _p3.get("wip_urn") or "").strip() or _p3d_urn         except Exception:             pass+        _p3d_urn = _p3d_urn or (args.get("f3dUrn") or "").strip()         opened3d = None         if _p3d_urn:             opened3d = dispatch_command("open_by_urn", {"urn": _p3d_urn})@@ -9339,6 +9363,11 @@ def _handle_prove_library(fusion_info: dict, args: dict) -> dict:         except Exception as _e:             missing.append("thumbnail(check-failed)")     captured = [e for e in evidence if e.get("ok") and e.get("screenshot")]+    # A failed FRAME belongs in `missing` too (run 7d4427d443f5 read "missing=[]" while+    # 2 of 4 frames had failed - the reader should never have to diff the evidence list+    # to learn what is absent).+    missing += ["frame:%s(%s)" % (e.get("step"), str(e.get("error"))[:60])+                for e in evidence if not (e.get("ok") and e.get("screenshot"))]     proven = (not missing) and len(captured) == 4     out = {"success": proven, "proven": proven, "libraryPath": lbr, "deviceset": want,            "artifacts": artifacts, "missing": missing,@@ -9750,8 +9779,11 @@ def _handle_create_library(fusion_info: dict, args: dict) -> dict:                     state.update(stage="failed", success=False); _save(); return                 _leave("bind")             _enter("proving (four evidence frames)")-            prove = _handle_prove_library(fusion_info, {"libraryPath": target_lbr,-                                                        "name": args.get("name")})+            prove = _handle_prove_library(fusion_info, {+                "libraryPath": target_lbr, "name": args.get("name"),+                # the bind just told us exactly which f3d holds the geometry - hand it on so+                # the 3D frame never depends on re-parsing the lbr for it+                "f3dUrn": ((state.get("bind") or {}).get("wip_urn") or "")})             _leave("prove")             state.update(stage="done", success=bool(prove.get("proven")), prove=prove)             _save()