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 170 file(s)
15 files changed
+69−35
BRIDGE_VERSION+1−1@@ -1 +1 @@-1.11.30+1.11.31
bridge.json+3−1@@ -2,7 +2,7 @@ "manifest_version": 1, "name": "fusion360", "displayName": "Autodesk Fusion 360",- "version": "1.11.30",+ "version": "1.11.31", "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.",@@ -49,6 +49,7 @@ "fusion_bind_library_3d", "fusion_board_bom", "fusion_board_info",+ "fusion_board_seed", "fusion_board_source", "fusion_board_stackup", "fusion_build_library_3d",@@ -164,6 +165,7 @@ "fusion_run_modeling_script", "fusion_save_to_cloud", "fusion_schematic",+ "fusion_schematic_plan", "fusion_schematic_run", "fusion_screenshot_fusion", "fusion_search_cloud_files",
contracts/describe.json+41@@ -509,6 +509,28 @@ "summary": "Raw board geometry XML (copper/arcs/lines) for the open board.", "timeoutSeconds": 60 },+ {+ "example": {},+ "input": {+ "fixed": "optional [{ref, deviceset, value?, x, y (mm, board frame), rot?, nets:{pin:net}}]",+ "libraryPath": "required .lbr on this machine",+ "name": "optional design name (letters, digits, _ -)",+ "outDir": "required folder on this machine",+ "outlineMm": "required [width, height]",+ "rules": "optional {clearance, edge, minWidth, minDrill, holeToHole, padRestringRatio, padRestring, viaRestring, copperUm}",+ "title": "optional sheet title"+ },+ "longRunning": false,+ "name": "fusion_board_seed",+ "output": {+ "brdPath": "str",+ "fixedParts": "int",+ "schPath": "str"+ },+ "statusVerb": "fusion_get_app_state",+ "summary": "Write the design a new board starts from, as EAGLE source on this machine: the board outline, the fab's design rules (Fusion's own rules block with your clearance, edge distance, minimum width and drill, hole-to-hole, pad and via restring and copper weight; Fusion's defaults are 0.35 mm drill, 1 mm to the edge and a 25 % pad restring, wrong for most fabs), the fixed parts at their places with their nets, and the library they come from. Then fusion_new_electronics_from_eagle imports it as a linked schematic and board.",+ "timeoutSeconds": 60+ }, { "example": {}, "input": {@@ -2779,6 +2801,25 @@ "summary": "START HERE for a schematic. ONE verb, three actions. action:\"open\" lands in the schematic editor from whatever names the design: fileName (+projectName) or urn or query for a CLOUD design (opens it, then switches to the schematic view), schPath for a local EAGLE .sch (its sibling .brd is imported with it so parts instantiate, unless withBoard:false; a .sch alone opens dialog-free), or filePath for a Fusion-native .fsch. action:\"create\" writes a blank EAGLE schematic on the box and opens it as a NEW local electronics design with the schematic editor active, no dialog anywhere. action:\"show\" switches the already-open design to its schematic view. Every reply says which underlying verb it used (via). Remember: a schematic is a VIEW of an electronics design, not a file of its own, which is why there is no verb called open_a_schematic_file. To put a library's parts on a NEW schematic and board for showing them off, use fusion_make_showcase_project instead.", "timeoutSeconds": 240 },+ {+ "example": {},+ "input": {+ "columns": "optional frames per row (default 3)",+ "libraryPath": "required .lbr on this machine",+ "nets": "required {net:[ref.pin or ref.pad]}",+ "parts": "required [{ref, deviceset, value?, block?}]"+ },+ "longRunning": false,+ "name": "fusion_schematic_plan",+ "output": {+ "commandCount": "int",+ "groups": "[{group, parts, commands}]",+ "notInParts": "[str]"+ },+ "statusVerb": "fusion_get_app_state",+ "summary": "Plan a grouped schematic from a netlist: one labelled frame per block, the block's parts in a row, every connected pin given a short stub named for its net and a label. Returns the command groups for fusion_schematic_run (one call per group, so the sheet grows block by block on camera). Pins may be named by pad (U1.3) or pin (U1.VIN). Pure computation from the .lbr; nothing in Fusion changes.",+ "timeoutSeconds": 60+ }, { "example": {}, "input": {
dashboard/Cargo.lock+1−1@@ -4,7 +4,7 @@ version = 4 [[package]] name = "fusion-dashboard"-version = "1.11.30"+version = "1.11.31" dependencies = [ "serde_json", ]
dashboard/Cargo.toml+1−1@@ -1,6 +1,6 @@ [package] name = "fusion-dashboard"-version = "1.11.30"+version = "1.11.31" edition = "2021" [dependencies]
describe.py+6@@ -46,6 +46,12 @@ _T = [ ("fusion_change_pours", "Change existing pours in place: the pen width (the narrowest copper the fill can reach; a pen wider than a throat leaves it empty) and the isolation. Each pour is named by net, layer and outline, picked on the midpoint of its longest edge, then RATSNEST refills. The readback proves each pour took its new width/isolate and that no track or via changed, and reports the filled area before and after.", {"expectDocument":"required exact board name","boardId":"required","expectedRevision":"required","pours":"required [{net, layer, points:[[x,y]...], width? (mm), isolate? (mm)}]"}, {"success":"bool","verified":"bool","changes":"[{net,layer,width:[before,after],isolate:[before,after],filledMm2:[before,after]}]","revision":"str"},120,"fusion_routing_state",False,{}),+ ("fusion_board_seed", "Write the design a new board starts from, as EAGLE source on this machine: the board outline, the fab's design rules (Fusion's own rules block with your clearance, edge distance, minimum width and drill, hole-to-hole, pad and via restring and copper weight; Fusion's defaults are 0.35 mm drill, 1 mm to the edge and a 25 % pad restring, wrong for most fabs), the fixed parts at their places with their nets, and the library they come from. Then fusion_new_electronics_from_eagle imports it as a linked schematic and board.",+ {"libraryPath":"required .lbr on this machine","outDir":"required folder on this machine","name":"optional design name (letters, digits, _ -)","title":"optional sheet title","outlineMm":"required [width, height]","fixed":"optional [{ref, deviceset, value?, x, y (mm, board frame), rot?, nets:{pin:net}}]","rules":"optional {clearance, edge, minWidth, minDrill, holeToHole, padRestringRatio, padRestring, viaRestring, copperUm}"},+ {"schPath":"str","brdPath":"str","fixedParts":"int"},60,"fusion_get_app_state",False,{}),+ ("fusion_schematic_plan", "Plan a grouped schematic from a netlist: one labelled frame per block, the block's parts in a row, every connected pin given a short stub named for its net and a label. Returns the command groups for fusion_schematic_run (one call per group, so the sheet grows block by block on camera). Pins may be named by pad (U1.3) or pin (U1.VIN). Pure computation from the .lbr; nothing in Fusion changes.",+ {"libraryPath":"required .lbr on this machine","parts":"required [{ref, deviceset, value?, block?}]","nets":"required {net:[ref.pin or ref.pad]}","columns":"optional frames per row (default 3)"},+ {"groups":"[{group, parts, commands}]","commandCount":"int","notInParts":"[str]"},60,"fusion_get_app_state",False,{}), ("fusion_board_source", "Read the live board as EAGLE XML from a fresh export: parts, copper, vias, pours with Fusion's own computed fill, and the outline. Read-only. Feed it to adom-fields (it reads .brd) for current and heat, or to adom-aiflow, which converts it for its offline checks.", {"expectDocument":"required exact board name","boardId":"optional"}, {"source":"str (EAGLE .brd XML)","boardId":"str","revision":"str"},60,"fusion_routing_state",False,{}),
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.11.30"+DASH_VERSION="1.11.31" 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.11.30",+ "version": "1.11.31", "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+10−26@@ -1,6 +1,6 @@ { "slug": "fusion-bridge",- "version": "1.11.30",+ "version": "1.11.31", "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",@@ -76,6 +80,9 @@ "add a 3d model to a component", "make a fusion 360 library with 3d", "set up the fusion bridge",+ "fusion dashboard",+ "fusion status page",+ "open the fusion launch page", "aps not configured", "share aps client id across my org", "set up fusion cloud search for my company",@@ -108,28 +115,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]"- }-}+ ]+}
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.11.30"+version = "1.11.31" edition = "2021" license = "MIT"
rust/bridge/src/routing.rs+3−2@@ -1,8 +1,9 @@ //! Routing operations execute together on Fusion's main thread through the existing //! script transport. Embedding the implementation avoids replacing a loaded add-in. use serde_json::{json, Value};-const SOURCE: &str = concat!(include_str!("routing_script.py"), "\n", include_str!("routing_planner.py"));-pub fn owns(cmd: &str) -> bool { matches!(cmd, "routing_state" | "route_net" | "routing_drc" | "plan_route" | "move_parts" | "place_vias" | "apply_pours" | "pour_state" | "board_source" | "ripup_nets" | "schematic_run" | "board_bom" | "change_pours") }+const SOURCE: &str = concat!(include_str!("routing_script.py"), "\n", include_str!("routing_planner.py"),+ "\nFUSION_DEFAULT_RULES = r'''", include_str!("fusion_default_designrules.xml"), "'''\n");+pub fn owns(cmd: &str) -> bool { matches!(cmd, "routing_state" | "route_net" | "routing_drc" | "plan_route" | "move_parts" | "place_vias" | "apply_pours" | "pour_state" | "board_source" | "ripup_nets" | "schematic_run" | "board_bom" | "change_pours" | "schematic_plan" | "board_seed") } pub fn call(cmd: &str, args: &Value, pass: &dyn Fn(&str, Value) -> Value) -> Value { let script = format!("import json\nexec({})\nresult=handle(app,json.loads({}),{})\n", serde_json::to_string(SOURCE).unwrap(),
tools/check-naming.shtools/check-portable.shtools/promote.shtools/release.sh