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 15 file(s)
9 files changed
+87−19
BRIDGE_VERSION+1−1@@ -1 +1 @@-1.9.208+1.9.209
adom-bridge-fusion-manifest.json+4−4@@ -1,10 +1,10 @@ { "manifest_version": 1, "name": "fusion360",- "version": "1.9.208",- "url": "https://wiki.adom.inc/download/adom/fusion-bridge/1.9.208/adom-bridge-fusion-v1.9.208.zip",- "sha256": "94a8322042721d9bdf84afa77ee3818a13b5a1ba1b6c0cb5129a87eaf201b1f2",- "size": 495990,+ "version": "1.9.209",+ "url": "https://wiki.adom.inc/download/adom/fusion-bridge/1.9.209/adom-bridge-fusion-v1.9.209.zip",+ "sha256": "ca5e84bea81f7b19ab79383ace76d1cde8f43d4bf067dabb9f42e270e3972b12",+ "size": 497196, "verbPrefixes": [ "fusion_" ],
bridge.json+1−1@@ -2,7 +2,7 @@ "manifest_version": 1, "name": "fusion360", "displayName": "Autodesk Fusion 360",- "version": "1.9.208",+ "version": "1.9.209", "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.208"+version = "1.9.209" dependencies = [ "serde_json", ]
dashboard/Cargo.toml+1−1@@ -1,6 +1,6 @@ [package] name = "fusion-dashboard"-version = "1.9.208"+version = "1.9.209" 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.208"+DASH_VERSION="1.9.209" 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.208",+ "version": "1.9.209", "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.208",+ "version": "1.9.209", "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+66−1@@ -9194,6 +9194,17 @@ def _orchestrate_bind_library_3d(args: dict) -> dict: "fresh mint) - EDIT %s.dev then screenshot to verify the render." % deviceset)} +def _lbr_has_package3d(lbr_path: str):+ """Does this .lbr carry a bound package3d? Returns True/False, or None when the file+ cannot be read (unknown is NOT False - a caller must be able to tell them apart)."""+ try:+ txt = open(lbr_path, encoding="utf-8", errors="replace").read()+ except Exception:+ return None+ m = re.search(r'<package3d[^>]*(?:\burn|\bwip_urn)="([^"]+)"', txt)+ return bool(m and m.group(1).strip())++ def _orchestrate_show_library(args: dict) -> dict: """Eight-surfaces contract (ab SDK, issue #30): the LIBRARY surface by its smallest name. libraryPath opens it (open_lbr); name alone handles the already-open case."""@@ -9214,7 +9225,61 @@ def _orchestrate_show_library(args: dict) -> dict: "_hint": "Pass libraryPath (WINDOWS .lbr path) to open it; name alone only handles the already-open case."} else: return {"success": False, "error": "libraryPath or name required."}- out = {"success": True, "view": "library"}+ # ── FINDING 2 (#58): ASSERT THE LIBRARY IS ACTUALLY THE ACTIVE DOCUMENT ────────────+ # One call returned success:true with Fusion sitting on an empty Untitled(1) DESIGN+ # tab, no Electronics panels at all, and nothing in the response distinguished it from+ # the nine that worked. Worse, the reporter's blank-frame smoke alarm RATED IT BEST:+ # 99.5% ink coverage vs 94.5-94.7% for the real ones, because a uniform dark canvas is+ # "inked" everywhere. A screenshot cannot be the proof here; the document name can.+ want = (name or (lbr.rsplit("/", 1)[-1].rsplit(".", 1)[0] if lbr else "")).strip()+ active = ""+ try:+ st = _proxy_to_addin("get_app_state", {}, timeout=12)+ active = str((st.get("data") or {}).get("activeDocument", "") or "")+ except Exception:+ pass+ if want and active and want.lower() not in active.lower():+ return {"success": False, "errorCode": "library_not_active",+ "error": "opened %r but the ACTIVE document is %r - the view you would "+ "screenshot is not the library." % (want, active),+ "activeDocument": active, "expected": want,+ "_hint": ("Fusion switched or left another tab in front. Re-call "+ "fusion_show_library {libraryPath} once; if it repeats, close the "+ "stray document (fusion_close_document) and retry.")}++ out = {"success": True, "view": "library", "activeDocument": active or None}++ # ── THE HINT REQUEST (#58): say when there is no 3D to show ────────────────────────+ # The reporter called this verb alone, got a grey Placeholder in the 3D pane on 10/10+ # parts, and filed it as a bridge bug before finding their own documentation saying+ # fusion_bind_library_3d must run first. They are right that the bridge KNOWS this and+ # said nothing. threeDBound is null when unknowable (name-only call), never False.+ bound = _lbr_has_package3d(lbr) if lbr else None+ out["threeDBound"] = bound+ if bound is False:+ out["_hint"] = ("This library has NO package3d, so Fusion renders a grey Placeholder "+ "slab in the 3D pane - that is not a captured 3D artifact. Run "+ "fusion_bind_library_3d {libraryPath, stepPath} FIRST, then re-open. "+ "(fusion_create_library does the whole chain for you.)")+ elif bound is None and lbr:+ out["_hint"] = ("Could not read the .lbr to tell whether a package3d is bound; if the "+ "3D pane shows a grey Placeholder, run fusion_bind_library_3d first.")++ # ── FINDING 3 (#58): ten calls left ten tabs open ──────────────────────────────────+ # Not closed automatically: showing a library is a "leave it on screen" verb, so+ # closing it would defeat the call. Reported instead, so a batch caller can see the+ # accumulation it is causing rather than discovering it ten tabs later.+ try:+ _docs = _open_doc_names()+ if len(_docs) > 3:+ out["openDocuments"] = len(_docs)+ out["_hintDocs"] = ("%d documents are open in Fusion. show_library deliberately "+ "leaves the library on screen, so a batch of calls accumulates "+ "tabs - close them with fusion_close_all_documents between "+ "runs." % len(_docs))+ except Exception:+ pass+ try: shot = _handle_screenshot_fusion({}, {}) p = shot.get("savedTo") or shot.get("localSafePath")