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
v1.9.72: design surface regeneration
8 files changed
+65−23
BRIDGE_VERSION+1−1@@ -1 +1 @@-1.9.71+1.9.72
CHANGELOG.md+10@@ -3,6 +3,16 @@ All notable changes to the Adom Bridge Fusion 360 bridge, newest first. Canonical: https://wiki.adom.inc/adom/fusion-bridge · GitHub backup: `adom-inc/fusion-bridge` +## 1.9.72 - 2026-08-18 (ralph)++- **Design surfaces regenerate their project on demand.** Staging cached itself as complete even+ when `make_test_project` failed (it can fail if Fusion is mid-restart), so every later design+ click paid a full re-heal and still failed. The staging cache now records `designReady`, and a+ design click regenerates just the project - after calling ensure_ready first, which the cached+ path was skipping (a doctrine gap in my own new code, caught in the same loop).+ Verified: schematic went from failing to opening in 221s including a Fusion relaunch.+- Dashboard/bridge back in version lockstep (both 1.9.72).+ ## 1.9.71 - 2026-08-18 (ralph) - **The DESIGN surfaces survive a bridge respawn.** show_project / show_schematic / show_2d_board /
adom-bridge-fusion-manifest.json+4−4@@ -1,10 +1,10 @@ { "manifest_version": 1, "name": "fusion360",- "version": "1.9.71",- "url": "https://wiki.adom.inc/download/adom/fusion-bridge/1.9.71/adom-bridge-fusion-v1.9.71.zip",- "sha256": "ecaa27e89c81db89cf24d2da7e035887a57d79f5e5ec1f9b6574f7ea7be0d36c",- "size": 409291,+ "version": "1.9.72",+ "url": "https://wiki.adom.inc/download/adom/fusion-bridge/1.9.72/adom-bridge-fusion-v1.9.72.zip",+ "sha256": "18b4365ec71d90c26ef39554eba77a863efdad5161ff7dcc0ad3ef29976011bb",+ "size": 409290, "verbPrefixes": [ "fusion_" ],
bin/fusion-dashboard⋯ 1 unchanged line ⋯
dashboard/Cargo.toml+1−1@@ -1,6 +1,6 @@ [package] name = "fusion-dashboard"-version = "1.9.67"+version = "1.9.72" edition = "2021" [dependencies]
dashboard/src/main.rs+37−8@@ -234,7 +234,9 @@ struct App { // Surfaces demo staging, keyed BY TARGET: staging sends files to one specific box, so a // single global slot made a switch to another box reuse paths that box never received // (caught live 2026-08-18).- staged: Mutex<std::collections::HashMap<String, (String, String)>>,+ // (libraryPath, deviceset, designReady) - designReady false means the generated test+ // project did NOT land, so the four design surfaces must regenerate it before they run.+ staged: Mutex<std::collections::HashMap<String, (String, String, bool)>>, } // ── Dashboard-own settings (container-side; bridge prefs stay in the bridge) ──────────────@@ -476,7 +478,7 @@ const SURFACES: [(&str, &str, &str); 8] = [ ("project", "fusion_show_project", "Project"), ]; -fn stage_demo_part(app: &Arc<App>, target: &str, page: &str) -> Result<(String, String), String> {+fn stage_demo_part(app: &Arc<App>, target: &str, page: &str) -> Result<(String, String, bool), String> { let cache_key = format!("{}|{}", target, page); if let Some(hit) = app.staged.lock().unwrap().get(&cache_key).cloned() { return Ok(hit); } let ai = app.ai_thread.clone();@@ -523,13 +525,17 @@ fn stage_demo_part(app: &Arc<App>, target: &str, page: &str) -> Result<(String, toast("Generating a solo test project around the part", ""); let mp = unwrap_data(&bridge(&ai, target, "fusion_make_test_project", &serde_json::json!({"libraryPath": win_lbr}).to_string()));- if mp["success"].as_bool() != Some(true) {- // Component surfaces still work without the design half - report, do not abort.- toast("Design surfaces unavailable (test project generation failed) - component surfaces still work", "err");+ let design_ok = mp["success"].as_bool() == Some(true);+ if !design_ok {+ // Component surfaces still work without the design half. Record the FAILURE so a later+ // design click regenerates just the project instead of assuming it exists (ralph,+ // 2026-08-18: it failed while Fusion was mid-restart and every design surface then paid+ // a full re-heal + re-stage cycle).+ toast("Design surfaces need the test project - I will generate it when you click one", ""); }- app.staged.lock().unwrap().insert(cache_key, (win_lbr.clone(), deviceset.clone()));+ app.staged.lock().unwrap().insert(cache_key, (win_lbr.clone(), deviceset.clone(), design_ok)); toast(&format!("{} staged - every surface button is live", deviceset), "ok");- Ok((win_lbr, deviceset))+ Ok((win_lbr, deviceset, design_ok)) } fn show_surface(app: &Arc<App>, target: &str, key: &str, page: &str) -> serde_json::Value {@@ -537,10 +543,33 @@ fn show_surface(app: &Arc<App>, target: &str, key: &str, page: &str) -> serde_js Some((_, v, l)) => (*v, *l), None => return serde_json::json!({"error": format!("unknown surface {}", key)}), };- let (lib, dev) = match stage_demo_part(app, target, page) {+ let (lib, dev, mut design_ok) = match stage_demo_part(app, target, page) { Ok(x) => x, Err(e) => return serde_json::json!({"error": e}), };+ let is_design = matches!(key, "project" | "schematic" | "board2d" | "board3d");+ if is_design && !design_ok {+ // DOCTRINE: get the box ready first - this path runs from a CACHED staging, so it skips+ // stage_demo_part's own ensure_ready and would otherwise fail with "not running" the+ // moment Fusion closed or the Autodesk seat moved (ralph, 2026-08-18).+ if !ensure_ready(app, target, 240) {+ return serde_json::json!({"surface": key, "label": label, "ok": false,+ "error": format!("Fusion did not become ready on {} in time", target),+ "_hint": "Open Settings and read the status cards - a sign-in wall or a stuck launch is reported there."});+ }+ app.hub.broadcast("toast", &serde_json::json!({+ "message": "Generating the test project for the design surfaces", "kind": ""}));+ let mp = unwrap_data(&bridge(&app.ai_thread, target, "fusion_make_test_project",+ &serde_json::json!({"libraryPath": lib}).to_string()));+ design_ok = mp["success"].as_bool() == Some(true);+ app.staged.lock().unwrap().insert(format!("{}|{}", target, page),+ (lib.clone(), dev.clone(), design_ok));+ if !design_ok {+ return serde_json::json!({"surface": key, "label": label, "ok": false,+ "error": format!("could not generate the test project: {}", mp["error"]),+ "_hint": "The design surfaces need a generated project; the component surfaces (symbol, footprint, 3D package, library) work without it."});+ }+ } let ai = app.ai_thread.clone(); let args = match key { "symbol" | "footprint" | "package3d" => serde_json::json!({"name": dev, "libraryPath": lib}),
package.json+1−1@@ -1,6 +1,6 @@ { "slug": "fusion-bridge",- "version": "1.9.65",+ "version": "1.9.72", "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,16 +1,20 @@ { "slug": "fusion-bridge",- "version": "1.9.65",+ "version": "1.9.72", "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": {- "adom/adom-desktop": "*"+ "adom/adom-desktop": "^1.9.0" }, "scripts": { "install": "./install.sh", "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]"- }+ ] }