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
Update 102 file(s)
9 files changed
+57−23
BRIDGE_VERSION+1−1@@ -1 +1 @@-1.9.279+1.9.280
adom-bridge-fusion-manifest.json+4−4@@ -1,10 +1,10 @@ { "manifest_version": 1, "name": "fusion360",- "version": "1.9.279",- "url": "https://wiki.adom.inc/download/adom/fusion-bridge/1.9.279/adom-bridge-fusion-v1.9.279.zip",- "sha256": "78e37e369f5fc8cbf486b3b35d3b5d744582ffb7d4d8b80faa3f3c6914f8f9a7",- "size": 570705,+ "version": "1.9.280",+ "url": "https://wiki.adom.inc/download/adom/fusion-bridge/1.9.280/adom-bridge-fusion-v1.9.280.zip",+ "sha256": "c199d0b73a122463454dd0402c605ac40fa95deb099e27b0fd093d9f6ad4a900",+ "size": 571489, "verbPrefixes": [ "fusion_" ],
bridge.json+1−1@@ -2,7 +2,7 @@ "manifest_version": 1, "name": "fusion360", "displayName": "Autodesk Fusion 360",- "version": "1.9.279",+ "version": "1.9.280", "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.",
dashboard/Cargo.lock+1−1@@ -4,7 +4,7 @@ version = 4 [[package]] name = "fusion-dashboard"-version = "1.9.279"+version = "1.9.280" dependencies = [ "serde_json", ]
dashboard/Cargo.toml+1−1@@ -1,6 +1,6 @@ [package] name = "fusion-dashboard"-version = "1.9.279"+version = "1.9.280" edition = "2021" [dependencies]
install.sh+1−1@@ -21,7 +21,7 @@ echo "Installed fusion-bridge skills: $(ls "$PKG_DIR/skills" 2>/dev/null | tr '\ # binary (the three-artifact pattern: bridge zip -> ab, THIS pkg -> container skills + # this download, page media -> wiki). Per the wiki's PKG_VS_RELEASE policy, binaries are # platform-tagged RELEASE assets, never tarball content - the installer fetches them.-DASH_VERSION="1.9.279"+DASH_VERSION="1.9.280" DASH_URL="https://wiki.adom.inc/download/adom/fusion-bridge/${DASH_VERSION}/fusion-dashboard" DEST="" if [ -w /usr/local/bin ]; then DEST=/usr/local/bin
package.json+1−1@@ -1,6 +1,6 @@ { "slug": "fusion-bridge",- "version": "1.9.279",+ "version": "1.9.280", "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+11−8@@ -1,6 +1,6 @@ { "slug": "fusion-bridge",- "version": "1.9.279",+ "version": "1.9.280", "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",@@ -75,7 +79,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.",@@ -104,9 +111,5 @@ "label": "Part volume", "prompt": "How much material does each printed part in this assembly use?" }- ],- "author": {- "name": "John Lauer",- "email": "[email protected]"- }-}+ ]+}
server.py+36−5@@ -11426,9 +11426,19 @@ def _handle_prove_library(fusion_info: dict, args: dict) -> dict: _LAST_LIBRARY[0] = lbr evidence = []+ # SHARED PACKAGE, PROVE ONCE (John, 2026-08-30: "once you have a correctly defined+ # footprint with 3d attached, you don't need to re-bind each time ... this process+ # literally took you all night"). The bind was already once per package; the PROOF was+ # not: nine symbol variants on one SOIC-16 re-opened the same footprint and the same+ # cloud 3D design nine times. The chain now passes _skipSteps for a deviceset whose+ # package was proved earlier in the run; only its symbol and ganged frames are taken.+ _skip = set(args.get("_skipSteps") or [])+ _shared_with = args.get("_sharedWith") # 1 + 2: the two editors, each full screen. for label, suffix, view in (("symbol", "sym", "symbol-editor"), ("footprint", "pac", "footprint-editor")):+ if label in _skip:+ continue r = _show_library_view(want, suffix, lbr) if not r.get("success"): evidence.append(_emit({"step": label, "view": view, "ok": False,@@ -11437,7 +11447,7 @@ def _handle_prove_library(fusion_info: dict, args: dict) -> dict: evidence.append(_emit(_prove_capture(label, view))) # 3: the 3D editor. Only reachable when a real package3d is bound - with none, Fusion # shows its Placeholder, which is exactly the false pass this verb exists to prevent.- if artifacts["package3d"]["present"]:+ if artifacts["package3d"]["present"] and "package3d" not in _skip: # THE BOUND MODEL, NOT THE GENERATOR (caught by the bodies gate, run be27c38d034e: # 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@@ -11574,7 +11584,7 @@ def _handle_prove_library(fusion_info: dict, args: dict) -> dict: "error": "Could not open the bound f3d (%s): %s" % ( _p3d_urn[-30:] if _p3d_urn else "no urn", str((opened3d or {}).get("error"))[:100])}))- else:+ elif "package3d" not in _skip: evidence.append(_emit({"step": "package3d", "view": "3d-editor", "ok": False, "error": "No package3d bound - the 3D editor would only show Fusion's " "grey Placeholder, which is not evidence."}))@@ -11624,9 +11634,11 @@ def _handle_prove_library(fusion_info: dict, args: dict) -> dict: # of every message began - "Fusion offere[d ...]" - and cost the reporter a diagnosis) missing += ["frame:%s(%s)" % (e.get("step"), str(e.get("error"))) for e in evidence if not (e.get("ok") and e.get("screenshot"))]- proven = (not missing) and len(captured) == 4+ _expected = 4 - len(_skip & {"symbol", "footprint", "package3d", "ganged"})+ proven = (not missing) and len(captured) == _expected out = {"success": proven, "proven": proven, "libraryPath": lbr, "deviceset": want, "artifacts": artifacts, "missing": missing,+ "stepsSkipped": sorted(_skip), "sharedPackageProof": _shared_with, "evidence": evidence, "imagesCaptured": len(captured), "imagesRequired": 4} if thumb_unverified: out["thumbnailUnverified"] = thumb_unverified@@ -12993,7 +13005,7 @@ def _handle_create_library(fusion_info: dict, args: dict) -> dict: # Total is parts x 4, not a literal 4: on the first real 2-part run this # read "captured symbol (5 of 4)" - a narration line the front end renders # under the progress bar, reading nonsense from part two onward.- _tot = 4 * max(1, int(state.get("partsToProve") or state.get("partsTotal") or 1))+ _tot = int(state.get("framesExpected") or 0) or 4 * max(1, int(state.get("partsToProve") or state.get("partsTotal") or 1)) state["stageLabel"] = ("part %s of %s: captured %s (frame %d of %d)" % (state.get("partIndex") or "?", state.get("partsToProve") or "?", entry.get("step"), len(ev), _tot))@@ -13025,6 +13037,18 @@ def _handle_create_library(fusion_info: dict, args: dict) -> dict: state["provedParts"] = [] _prove_results, _all_ok = [], True _last_beat = [_tc.time()]+ # ONE FOOTPRINT + 3D PROOF PER PACKAGE (John, 2026-08-30). Devicesets that share a+ # package (symbol variants, value clones) get only their symbol and ganged frames;+ # the footprint and the cloud 3D design were proved with the first deviceset on+ # that package. Nine CH340G variants: 20 frames instead of 36, and the slow 3D+ # open happens once instead of nine times.+ try:+ _dev_pac = _library_artifact_names(target_lbr).get("dev_pac") or {}+ except Exception:+ _dev_pac = {}+ _pkg_proved_by = {}+ _uniq_pkgs = len({tuple(v) for v in _dev_pac.values()}) or len(_targets)+ state["framesExpected"] = 4 * min(_uniq_pkgs, len(_targets)) + 2 * max(0, len(_targets) - _uniq_pkgs) for _pi, _dev in enumerate(_targets, 1): # A RUN MUST NOT OUTLIVE A SLEEP (John, 2026-08-30: "it seems odd to me that # its the next morning and you're still running this job"). The chain lives@@ -13067,14 +13091,21 @@ def _handle_create_library(fusion_info: dict, args: dict) -> dict: entry["kind"] = "proof" # vs "main"/"popup" from fusion_live_feed return _publish_frame(entry) + _pk_key = tuple(_dev_pac.get(_dev) or [])+ _shared = _pkg_proved_by.get(_pk_key) if _pk_key else None _r = _handle_prove_library(fusion_info, { "libraryPath": target_lbr, "name": _dev, # 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 ""),+ "_skipSteps": (["footprint", "package3d"] if _shared else []),+ "_sharedWith": _shared, "_onFrame": _frame_for}) _prove_results.append({"part": _dev, "proven": bool(_r.get("proven")),- "error": _r.get("error")})+ "error": _r.get("error"),+ "sharedPackageProof": _shared})+ if _r.get("proven") and _pk_key and not _shared:+ _pkg_proved_by[_pk_key] = _dev state["provedParts"] = _prove_results _all_ok = _all_ok and bool(_r.get("proven")) # Close what THIS deviceset's frames opened (the 3D frame's design, any