← Commit history
CHANGELOG.md+8
@@ -3,6 +3,14 @@ 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.13.40 (2026-10-30)++- Issue #133, second half: the EAGLE import's wait for the new design compared the workspace's NAME (PCB Editor), but+  add-in 1.0.29 (1.13.38's #131 fix) answered the workspace's ID (BoardLayoutEnvironement), so a successful import+  (live: both dialogs taken, 109 of 109 parts placed) was reported as nothing_instantiated. Add-in 1.0.30 answers the+  name again (activeWorkspace, as DebugCommands.ActiveWorkspace did) with the id beside it (activeWorkspaceId), and the+  import wait and library_views accept either, so a Fusion still on add-in 1.0.29 works too.+ ## 1.13.39 (2026-10-30)  - Issue #133 (Andy Engevold, AI Flow): `fusion_new_electronics_from_eagle` left Fusion's native Open dialog up, empty,
addin/AdomBridge/AdomBridge.manifest+1−1
@@ -6,7 +6,7 @@     "description": {         "": "Adom Desktop Conduit bridge add-in. Exposes a localhost HTTP API for external automation of Fusion 360."     },-    "version": "1.0.29",+    "version": "1.0.30",     "runOnStartup": true,     "supportedOS": "windows" }\ No newline at end of file
addin/AdomBridge/commands/app_state.py+3−1
@@ -12,8 +12,9 @@ def handle_get_app_state(app: adsk.core.Application, args: dict) -> dict:     # The workspace and whether an electronics editor is in front, read from the API: this read is     # polled (readiness, the dashboard, waits), and a text command here (Electron.run DISPLAY) ended     # the user's MOVE in progress every time (issue #131)-    from .ui_state import active_workspace as _ws, is_electronics as _is_el, user_command_active as _busy+    from .ui_state import active_workspace as _ws, active_workspace_id as _ws_id, is_electronics as _is_el, user_command_active as _busy     active_workspace = _ws(app)+    workspace_id = _ws_id(app)     is_electronics = _is_el(app)     user_command = _busy(app) @@ -96,6 +97,7 @@ def handle_get_app_state(app: adsk.core.Application, args: dict) -> dict:             "productType": product_type,             "isElectronics": is_electronics,             "userCommandActive": user_command,+            "activeWorkspaceId": workspace_id,             "documents": documents,         },         "_hint": hint,
addin/AdomBridge/commands/ui_state.py+13−3
@@ -7,17 +7,27 @@ import adsk.core   def active_workspace(app: adsk.core.Application) -> str:-    """The workspace in front by its id (BoardLayoutEnvironement, SchematicEnvironment ...: the same-    names DebugCommands.ActiveWorkspace answered), or 'unknown'."""+    """The workspace in front by its name (PCB Editor, Schematic Editor, Electronics Library ...: what+    DebugCommands.ActiveWorkspace answered and what the bridge's checks compare), or 'unknown'.+    1.0.29 answered the id (BoardLayoutEnvironement), which the EAGLE import's wait did not+    recognise (issue #133)."""     try:         ws = app.userInterface.activeWorkspace         if ws:-            return ws.id or ws.name or "unknown"+            return ws.name or ws.id or "unknown"     except Exception:         pass     return "unknown"  +def active_workspace_id(app: adsk.core.Application) -> str:+    try:+        ws = app.userInterface.activeWorkspace+        return (ws.id if ws else "") or ""+    except Exception:+        return ""++ def is_electronics(app: adsk.core.Application) -> bool:     """True when an electronics editor (schematic, board or library) is in front: its product is an     adsk::electron object."""
rust/bridge/src/orchestrations.rs+19−2
@@ -919,7 +919,8 @@ pub fn capture_library_views(ctx: &Ctx, args: &Value, pass: &dyn Fn(&str, Value)             let shot = capture_labeled(ctx, &format!("{pkg}_{}", label_of(ext)));             let st = pass("get_app_state", json!({}));             let editor_ws = st["data"]["activeWorkspace"].as_str().or(st["activeWorkspace"].as_str()).map(str::to_string);-            let editor_ok = match &editor_ws { Some(w) => w.to_lowercase().contains("electronics library"), None => false };+            // the name (Electronics Library) or, from add-in 1.0.29, the workspace id+            let editor_ok = match &editor_ws { Some(w) => { let l = w.to_lowercase(); l.contains("electronics library") || (l.contains("librar") && !l.contains("design")) }, None => false };             let mut entry = json!({"package": pkg, "view": label_of(ext), "path": shot, "dialogDismissed": if dismissed.is_empty() { Value::Null } else { json!(dismissed) }, "capturedInWorkspace": editor_ws,                 "ok": er["success"].as_bool().unwrap_or(true) && !entry_null(&shot) && dismissed.is_empty() && editor_ok});             if !editor_ok && editor_ws.is_none() { entry["errorCode"] = json!("editor_unverified"); entry["error"] = json!("Could not read which editor was active at capture time (the add-in did not answer), so this frame cannot be confirmed to show the view it is labelled with."); entry["_hint"] = json!("Not necessarily a bad frame - it is an unverified one. Check fusion_addin_status and re-capture."); }@@ -1232,6 +1233,13 @@ pub fn eagle_import_status(ctx: &Ctx, args: &Value) -> Value {     } } +/// A board or schematic editor in front, by the workspace's name (PCB Editor, Schematic Editor) or, as+/// add-in 1.0.29 answered, its id (BoardLayoutEnvironement, SchematicEnvironment ...).+fn electronics_editor(ws: &str) -> bool {+    let l = ws.to_lowercase();+    ["pcb editor", "schematic editor", "board layout", "3d pcb"].contains(&l.as_str()) || l.contains("boardlayout") || l.starts_with("schematic")+}+ /// Close the Untitled documents a failed import opened (more Untitled than before it started); a /// never-saved Untitled holds nothing of the user's. Returns how many were closed. fn close_new_untitled(before: &[String], pass: &dyn Fn(&str, Value) -> Value) -> usize {@@ -1388,7 +1396,7 @@ pub fn new_electronics_from_eagle(ctx: &Ctx, args: &Value, pass: &dyn Fn(&str, V         if i % 3 == 2 { if let Some(c) = crash_dialog() { return crashed(c, None, "waiting for the imported design", &picked); } }         let st = pass("get_app_state", json!({}));         let d = &st["data"];-        if d["isElectronics"].as_bool() == Some(true) && ["pcb editor", "schematic editor", "board layout", "3d pcb"].contains(&d["activeWorkspace"].as_str().unwrap_or("").to_lowercase().as_str()) { ready = true; doc_name = d["activeDocument"].as_str().unwrap_or("").to_string(); break; }+        if d["isElectronics"].as_bool() == Some(true) && electronics_editor(d["activeWorkspace"].as_str().unwrap_or("")) { ready = true; doc_name = d["activeDocument"].as_str().unwrap_or("").to_string(); break; }     }     // honest instantiation report (issue #90): what the .brd promised against what the board holds     let expected = std::fs::read_to_string(&brd).map(|t| t.matches("<element ").count()).unwrap_or(0);@@ -1533,3 +1541,12 @@ mod bound_p3d_tests {         assert_eq!(super::bound_p3d_urn(LBR, "Missing"), None);     } }++#[cfg(test)]+mod eagle_wait_tests {+    #[test]+    fn the_import_wait_knows_editors_by_name_or_id() {+        for w in ["PCB Editor", "Schematic Editor", "BoardLayoutEnvironement", "SchematicEnvironment"] { assert!(super::electronics_editor(w), "{w}"); }+        for w in ["Design", "FusionSolidEnvironment", "unknown", ""] { assert!(!super::electronics_editor(w), "{w}"); }+    }+}