← Commit history
BRIDGE_VERSION+1−1
@@ -1 +1 @@-1.10.26\ No newline at end of file+1.10.27\ No newline at end of file
bridge.json+1−1
@@ -2,7 +2,7 @@   "manifest_version": 1,   "name": "fusion360",   "displayName": "Autodesk Fusion 360",-  "version": "1.10.26",+  "version": "1.10.27",   "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.",
contracts/describe.json+6−3
@@ -2718,7 +2718,8 @@     {       "example": {},       "input": {-        "capture": "optional bool - ONE call = ONE consent: the bridge settles the surface (waits for the add-in main thread + a paint beat) and returns proof inline as shot:{title,image,thumbnailDataUrl,maxWidth} (base64 frame + a ready-to-use data: URL for BROWSER callers who cannot pull a file; set captureMaxWidth to shrink it - 320 keeps a /command body small, default 640. The bridge encodes PNG; the relay may transcode to WebP, so sniff rather than assume). Use this instead of polling fusion_state after a show - page-side settle polling costs one human consent per poll (issue #30)."+        "capture": "optional bool - ONE call = ONE consent: the bridge settles the surface (waits for the add-in main thread + a paint beat) and returns proof inline as shot:{title,image,thumbnailDataUrl,maxWidth} (base64 frame + a ready-to-use data: URL for BROWSER callers who cannot pull a file; set captureMaxWidth to shrink it - 320 keeps a /command body small, default 640. The bridge encodes PNG; the relay may transcode to WebP, so sniff rather than assume). Use this instead of polling fusion_state after a show - page-side settle polling costs one human consent per poll (issue #30).",+        "documentName": "optional str - the open document to show; the bridge activates it first (1.10.27). Pass it whenever more than one tab is open (a board plus its library is the usual pair); without it the verb acts on the ACTIVE document and answers not_an_electronics_design with openDocuments when a library or 3D design is in front"       },       "longRunning": true,       "name": "fusion_show_2d_board",@@ -2732,7 +2733,8 @@     {       "example": {},       "input": {-        "capture": "optional bool - ONE call = ONE consent: the bridge settles the surface (waits for the add-in main thread + a paint beat) and returns proof inline as shot:{title,image,thumbnailDataUrl,maxWidth} (base64 frame + a ready-to-use data: URL for BROWSER callers who cannot pull a file; set captureMaxWidth to shrink it - 320 keeps a /command body small, default 640. The bridge encodes PNG; the relay may transcode to WebP, so sniff rather than assume). Use this instead of polling fusion_state after a show - page-side settle polling costs one human consent per poll (issue #30)."+        "capture": "optional bool - ONE call = ONE consent: the bridge settles the surface (waits for the add-in main thread + a paint beat) and returns proof inline as shot:{title,image,thumbnailDataUrl,maxWidth} (base64 frame + a ready-to-use data: URL for BROWSER callers who cannot pull a file; set captureMaxWidth to shrink it - 320 keeps a /command body small, default 640. The bridge encodes PNG; the relay may transcode to WebP, so sniff rather than assume). Use this instead of polling fusion_state after a show - page-side settle polling costs one human consent per poll (issue #30).",+        "documentName": "optional str - the open document to show; the bridge activates it first (1.10.27). Pass it whenever more than one tab is open (a board plus its library is the usual pair); without it the verb acts on the ACTIVE document and answers not_an_electronics_design with openDocuments when a library or 3D design is in front"       },       "longRunning": true,       "name": "fusion_show_3d_board",@@ -2862,7 +2864,8 @@     {       "example": {},       "input": {-        "capture": "optional bool - ONE call = ONE consent: the bridge settles the surface (waits for the add-in main thread + a paint beat) and returns proof inline as shot:{title,image,thumbnailDataUrl,maxWidth} (base64 frame + a ready-to-use data: URL for BROWSER callers who cannot pull a file; set captureMaxWidth to shrink it - 320 keeps a /command body small, default 640. The bridge encodes PNG; the relay may transcode to WebP, so sniff rather than assume). Use this instead of polling fusion_state after a show - page-side settle polling costs one human consent per poll (issue #30)."+        "capture": "optional bool - ONE call = ONE consent: the bridge settles the surface (waits for the add-in main thread + a paint beat) and returns proof inline as shot:{title,image,thumbnailDataUrl,maxWidth} (base64 frame + a ready-to-use data: URL for BROWSER callers who cannot pull a file; set captureMaxWidth to shrink it - 320 keeps a /command body small, default 640. The bridge encodes PNG; the relay may transcode to WebP, so sniff rather than assume). Use this instead of polling fusion_state after a show - page-side settle polling costs one human consent per poll (issue #30).",+        "documentName": "optional str - the open document to show; the bridge activates it first (1.10.27). Pass it whenever more than one tab is open (a board plus its library is the usual pair); without it the verb acts on the ACTIVE document and answers not_an_electronics_design with openDocuments when a library or 3D design is in front"       },       "longRunning": true,       "name": "fusion_show_schematic",
dashboard/Cargo.lock+1−1
@@ -4,7 +4,7 @@ version = 4  [[package]] name = "fusion-dashboard"-version = "1.10.26"+version = "1.10.27" dependencies = [  "serde_json", ]
dashboard/Cargo.toml+1−1
@@ -1,6 +1,6 @@ [package] name = "fusion-dashboard"-version = "1.10.26"+version = "1.10.27" edition = "2021"  [dependencies]
describe.py+3−3
@@ -137,11 +137,11 @@ _T = [      # ── Electronics ────────────────────────────────────────────────────────     ("fusion_show_schematic", "Switch the OPEN electronics design to its SCHEMATIC view (the symmetric partner of fusion_show_2d_board / fusion_show_3d_board, via Fusion's SwitchSchDocCmd). A VIEW of the project, not a standalone file. Drive it for demos with fusion_electron_zoom / _pan / _select.",-     {"capture": "optional bool - ONE call = ONE consent: the bridge settles the surface (waits for the add-in main thread + a paint beat) and returns proof inline as shot:{title,image,thumbnailDataUrl,maxWidth} (base64 frame + a ready-to-use data: URL for BROWSER callers who cannot pull a file; set captureMaxWidth to shrink it - 320 keeps a /command body small, default 640. The bridge encodes PNG; the relay may transcode to WebP, so sniff rather than assume). Use this instead of polling fusion_state after a show - page-side settle polling costs one human consent per poll (issue #30)."}, {"success": "bool", "activeWorkspace": "str", "productType": "str"}, 70, None, True, {}),+     {"documentName": "optional str - the open document to show; the bridge activates it first (1.10.27). Pass it whenever more than one tab is open (a board plus its library is the usual pair); without it the verb acts on the ACTIVE document and answers not_an_electronics_design with openDocuments when a library or 3D design is in front", "capture": "optional bool - ONE call = ONE consent: the bridge settles the surface (waits for the add-in main thread + a paint beat) and returns proof inline as shot:{title,image,thumbnailDataUrl,maxWidth} (base64 frame + a ready-to-use data: URL for BROWSER callers who cannot pull a file; set captureMaxWidth to shrink it - 320 keeps a /command body small, default 640. The bridge encodes PNG; the relay may transcode to WebP, so sniff rather than assume). Use this instead of polling fusion_state after a show - page-side settle polling costs one human consent per poll (issue #30)."}, {"success": "bool", "activeWorkspace": "str", "productType": "str"}, 70, None, True, {}),     ("fusion_show_2d_board", "Switch the OPEN electronics design to its 2D PCB Editor (board layout) view. This is a VIEW of the project, not a file to open standalone - if the board is empty, you opened a child/derivative instead of the EcadDesignProductType PROJECT; reopen the project. Drive the view with fusion_electron_run WINDOW commands.",-     {"capture": "optional bool - ONE call = ONE consent: the bridge settles the surface (waits for the add-in main thread + a paint beat) and returns proof inline as shot:{title,image,thumbnailDataUrl,maxWidth} (base64 frame + a ready-to-use data: URL for BROWSER callers who cannot pull a file; set captureMaxWidth to shrink it - 320 keeps a /command body small, default 640. The bridge encodes PNG; the relay may transcode to WebP, so sniff rather than assume). Use this instead of polling fusion_state after a show - page-side settle polling costs one human consent per poll (issue #30)."}, {"activeWorkspace": "str"}, 70, None, True, {}),+     {"documentName": "optional str - the open document to show; the bridge activates it first (1.10.27). Pass it whenever more than one tab is open (a board plus its library is the usual pair); without it the verb acts on the ACTIVE document and answers not_an_electronics_design with openDocuments when a library or 3D design is in front", "capture": "optional bool - ONE call = ONE consent: the bridge settles the surface (waits for the add-in main thread + a paint beat) and returns proof inline as shot:{title,image,thumbnailDataUrl,maxWidth} (base64 frame + a ready-to-use data: URL for BROWSER callers who cannot pull a file; set captureMaxWidth to shrink it - 320 keeps a /command body small, default 640. The bridge encodes PNG; the relay may transcode to WebP, so sniff rather than assume). Use this instead of polling fusion_state after a show - page-side settle polling costs one human consent per poll (issue #30)."}, {"activeWorkspace": "str"}, 70, None, True, {}),     ("fusion_show_3d_board", "Switch the OPEN electronics design to its 3D PCB view (populated board). A VIEW of the project, not a standalone file. Orbit it for demos via fusion_run_modeling_script (app.activeViewport.camera + vp.refresh()).",-     {"capture": "optional bool - ONE call = ONE consent: the bridge settles the surface (waits for the add-in main thread + a paint beat) and returns proof inline as shot:{title,image,thumbnailDataUrl,maxWidth} (base64 frame + a ready-to-use data: URL for BROWSER callers who cannot pull a file; set captureMaxWidth to shrink it - 320 keeps a /command body small, default 640. The bridge encodes PNG; the relay may transcode to WebP, so sniff rather than assume). Use this instead of polling fusion_state after a show - page-side settle polling costs one human consent per poll (issue #30)."}, {"activeWorkspace": "str", "screenshots": "[...]"}, 70, None, True, {}),+     {"documentName": "optional str - the open document to show; the bridge activates it first (1.10.27). Pass it whenever more than one tab is open (a board plus its library is the usual pair); without it the verb acts on the ACTIVE document and answers not_an_electronics_design with openDocuments when a library or 3D design is in front", "capture": "optional bool - ONE call = ONE consent: the bridge settles the surface (waits for the add-in main thread + a paint beat) and returns proof inline as shot:{title,image,thumbnailDataUrl,maxWidth} (base64 frame + a ready-to-use data: URL for BROWSER callers who cannot pull a file; set captureMaxWidth to shrink it - 320 keeps a /command body small, default 640. The bridge encodes PNG; the relay may transcode to WebP, so sniff rather than assume). Use this instead of polling fusion_state after a show - page-side settle polling costs one human consent per poll (issue #30)."}, {"activeWorkspace": "str", "screenshots": "[...]"}, 70, None, True, {}),     ("fusion_open_by_urn_note", "(see fusion_open_by_urn)", {}, {}, 30, None, False, {}),     ("fusion_electronics_query", "TYPED electronics read model: rows for one of Autodesk's 49 electronics entity classes (Element, Signal, Net, Layer, Via, Smd, Wire, Pad, Part, Instance, Pin, Sheet, Package, Library, Error, Variant...) over the ACTIVE electronics document, with filters, field projection and pagination. Served by Autodesk's own MCP electronics_read when its server answers (fusion_mcp_enable turns it on), else by the board_info geometry export for Board/Element/Library/Package/Layer/Signal/Wire/Error (coordinates in mm). `source` names which. Replaces reading board_info XML by hand.",      {"entity": "required str (class name, with or without the electronics. prefix)", "fields": "optional [str] property names to return", "filters": "optional [{property, op: eq|lt|gt, value}] (strings: eq only)", "limit": "optional int (default 100)", "offset": "optional int", "source": "optional auto|mcp|board (default auto)"}, {"success": "bool", "source": "mcp|board", "entity": "str", "count": "int", "total": "int", "rows": "[dict]"}, 120, "fusion_get_app_state", False, {"entity": "Element", "fields": ["name", "x", "y", "angle"]}),
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.10.26"+DASH_VERSION="1.10.27" 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.10.26",+  "version": "1.10.27",   "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−27
@@ -1,6 +1,6 @@ {   "slug": "fusion-bridge",-  "version": "1.10.26",+  "version": "1.10.27",   "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,28 +111,5 @@       "label": "Part volume",       "prompt": "How much material does each printed part in this assembly use?"     }-  ],-  "agent_permissions": {-    "allow_bash": [],-    "allow": [-      "adom-desktop-fusion-bridge read-only verbs (via the adom-bridge CLI): fusion_readiness, fusion_get_app_state, fusion_addin_status, fusion_check_dialogs - state queries; they change nothing.",-      "adom-desktop-fusion-bridge read-only verbs: fusion_alerts (reads Fusion's own log for toasts), fusion_document_info, fusion_window_info, fusion_board_info, fusion_library_parts - inspect only.",-      "adom-desktop-fusion-bridge read-only verbs: fusion_prove_result (a persisted run report), fusion_plan_library_import (report-only preflight), fusion_list_cloud_projects, fusion_describe.",-      "adom-desktop-fusion-bridge evidence captures fusion_screenshot_fusion and fusion_capture_library_views read pixels and write local image files only."-    ],-    "soft_deny": [-      "adom-desktop-fusion-bridge lifecycle verbs fusion_stop, fusion_kill, fusion_restart_for_addin close or kill the Fusion application - keep the human prompt.",-      "adom-desktop-fusion-bridge fusion_install_fusion silently installs Autodesk Fusion on the user's machine.",-      "adom-desktop-fusion-bridge fusion_cleanup_cloud_files deletes files from the user's Autodesk cloud hub.",-      "adom-desktop-fusion-bridge managed-library verbs (fusion_managed_library_push/pull/create/link/unlink) publish to or overwrite the user's library.io libraries."-    ],-    "environment": [-      "adom-desktop-fusion-bridge is the Fusion 360 bridge for Adom Bridge; its fusion_* verbs are invoked through the adom-bridge CLI and drive Autodesk Fusion on the user's own desktop.",-      "adom-desktop-fusion-bridge desktop actions also pass Adom Bridge's own human-approval gate (caller identity, per-call reason, Activity Log) - a container approval is the first of two gates."-    ]-  },-  "author": {-    "name": "John Lauer",-    "email": "[email protected]"-  }-}\ No newline at end of file+  ]+}
rust/Cargo.toml+1−1
@@ -4,7 +4,7 @@ members = ["core", "lbr", "os-win", "os-mac", "bridge"]  # One version for the whole bridge, in lockstep with BRIDGE_VERSION (tools/release.sh bumps both). [workspace.package]-version = "1.10.26"+version = "1.10.27" edition = "2021" license = "MIT" 
rust/bridge/src/orchestrations.rs+19
@@ -520,7 +520,26 @@ pub fn show_project(ctx: &Ctx, args: &Value, pass: &dyn Fn(&str, Value) -> Value  /// `_handle_open_with_screenshot`: the add-in open or switch, then the post-open capture. pub fn open_with_screenshot(ctx: &Ctx, cmd: &str, args: &Value, pass: &dyn Fn(&str, Value) -> Value) -> Value {+    // A show verb acts on the ACTIVE document. With two or more tabs open (board + library is the+    // usual pair) the caller names the one it means; activating it here saves a failed round trip+    // (AdomLapper gate, 2026-09-20: show_2d_board failed because the library tab was in front).+    let is_show = matches!(cmd, "show_schematic" | "show_2d_board" | "show_3d_board");+    if is_show {+        if let Some(name) = args["documentName"].as_str().or_else(|| args["name"].as_str()).filter(|n| !n.is_empty()) {+            let a = pass("activate_document", json!({"name": name}));+            if a["success"].as_bool() == Some(false) {+                let mut a = a; a["_hint"] = json!(format!("{cmd} was asked to show '{name}' but that document could not be activated. fusion_state lists the open documents by name."));+                return a;+            }+        }+    }     let mut r = pass(cmd, args.clone());+    if is_show && r["success"].as_bool() == Some(false) && r["error"].as_str().map(|e| e.contains("open or create an electronics design")).unwrap_or(false) {+        let docs: Vec<Value> = r["documentHygiene"]["documents"].as_array().map(|a| a.iter().map(|d| d["name"].clone()).collect()).unwrap_or_default();+        r["errorCode"] = json!("not_an_electronics_design");+        r["openDocuments"] = json!(docs);+        r["_hint"] = json!(format!("The ACTIVE document is not an electronics design (a library or a 3D design is in front). Pass documentName to {cmd} and it activates that document first, e.g. {cmd} {{documentName:\"<board doc>\", capture:true}}. openDocuments lists what is open. Nothing open yet? fusion_schematic {{action:\"create\"}} or fusion_make_showcase_project make one, dialog-free."));+    }     if r["success"].as_bool() == Some(true) {         let (shots, _) = crate::lifecycle::post_open_screenshot(ctx, 2.0);         if !r["data"].is_object() { r["data"] = json!({}); }
skills/fusion-electronics/SKILL.md+3
@@ -44,6 +44,9 @@ PROJECT        EcadDesignProductType    <- OPEN THIS ONE The design is open; switch the LIVE editor between its three views with the symmetric trio: - `fusion_show_schematic` - the schematic (circuit diagram). Uses Fusion's `SwitchSchDocCmd`. - `fusion_show_2d_board` - the 2D PCB Editor (board layout / copper). `SwitchPcbDocCmd`.+- All three show verbs take `documentName`: with more than one tab open (a board plus its library is the+  usual pair) pass it and the bridge activates that document first. Without it they act on the ACTIVE+  document and answer `not_an_electronics_design` plus `openDocuments` when a library or 3D design is in front. - `fusion_show_3d_board` - the populated 3D PCB. `Switch3dPcbDocCmd`.  All three move the VISIBLE editor (not just the API's active doc), so they're what you use to set up a
tools/check-naming.sh

  
tools/check-portable.sh

  
tools/promote.sh

  
tools/release.sh