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
Publish 1.9.224
5 files changed
+169−12
describe.py+18−2@@ -234,8 +234,6 @@ _T = [ {"outputPath": "optional str", "side": "optional str (all|top|bottom)"}, {"topCount": "int", "bottomCount": "int"}, 60, None, False, {"outputPath": "C:/tmp/cpl.csv"}), ("fusion_set_design_rules", "Load manufacturing-grade DRC into the open board (JLCPCB 2/4-layer profiles).", {"action": "optional str (apply|export|show)", "layers": "optional str (auto|2|4)"}, {"activeWorkspace": "str", "description": "str"}, 90, None, False, {"action": "apply", "layers": "2"}),- ("fusion_load_design_rules", "Load a bundled .edru design-rule set into the board.",- {"layers": "optional str (auto|2|4)"}, {"success": "bool"}, 90, None, False, {}), ("fusion_detect_layers", "Detect 2-layer vs 4-layer board (ULP + CAM comparison).", {}, {"layerCount": "int", "copperLayers": "[int]"}, 90, None, False, {}), ("fusion_dismiss_blocking_dialogs", "Detect + classify (and optionally dismiss) blocking Fusion dialogs.",@@ -252,6 +250,24 @@ _T = [ {"name": "str (refdes, e.g. R1)", "x": "optional float", "y": "optional float", "properties": "optional bool (default true)"}, {"success": "bool", "output": "str", "deviceInfo": "str"}, 30, None, True, {"name": "U1"}), + ("fusion_prove_result", "POLL a background run started by fusion_create_library or the detached fusion_build_library_3d. Returns stage + stageLabel, plan[] with measured per-stage estimates, stagesDone, percent, etaSec, confidence, and evidence[] filling in AS EACH ARTIFACT LANDS (symbol -> footprint -> 3d -> ganged). For a 3D build it carries per-part progress (minting X (3/7)), partsDone/partsTotal and parts[] with each wip_urn. stage:done only means the chain FINISHED - the top-level verdict (proven/not_proven) is the score, and a run that captured zero frames lands stage:failed with blocked_by_dialog (carrying the dialog text) or no_evidence_captured rather than reporting done. Pass inlineFrames:true on the final fetch for base64 thumbnails a browser can render.",+ {"runId": "optional str (omit for the latest run)", "inlineFrames": "optional bool", "shots": "optional int", "sinceShot": "optional int"},+ {"stage": "str", "verdict": "str", "evidence": "[]", "percent": "float", "etaSec": "float"},+ 20, None, True, {"runId": "a3f1c2d4e5b6"}),+ ("fusion_addin_status", "Is the AdomBridge add-in loaded and answering inside Fusion? Reports addinReady, port and version, plus busy when a long command holds the main thread. If Fusion is running but this says not ready, the add-in was installed while Fusion was open - Fusion loads add-ins only at launch - so call fusion_restart_for_addin (ask the user first when one is present).",+ {}, {"addinReady": "bool", "port": "int", "version": "str", "busy": "bool"}, 15, None, True, {}),+ ("fusion_activate_document", "Make a named open document the ACTIVE one before driving it. EDIT and most modelling verbs act on whatever is active, so in a batch with several documents open this is how you stop a verb landing in the wrong file (page issue #47). Prefer passing expectDocument on the verb itself, which fails closed instead of merely re-targeting.",+ {"name": "required str (document name as reported by fusion_get_app_state)"},+ {"success": "bool", "activeDocument": "str"}, 60, None, False, {"name": "TJA1050"}),+ ("fusion_action_ledger", "Read the append-only record of what the bridge did in the BACKGROUND on this machine - dialogs it answered, Untitled scratch docs it swept, Fusion auto-starts, add-in restarts. Survives bridge respawns (~/.adom/fusion-bridge/actions.jsonl). This is the audit trail for why something changed on the user screen.",+ {"limit": "optional int (default 50)"}, {"actions": "[{at, action, detail}]"}, 15, None, True, {"limit": 20}),+ ("fusion_save_to_cloud", "Save the ACTIVE document to Autodesk cloud storage with an explicit name and destination. Dialog-free precisely because you supply what the Save box would ask for - use it before closing or restarting when a document has never been saved (fusion_close_all_documents refuses such a document with unsaved_named_document rather than discarding it).",+ {"name": "required str", "projectName": "optional str", "folderPath": "optional str", "description": "optional str"},+ {"success": "bool", "urn": "str"}, 180, None, False, {"name": "TJA1050", "projectName": "Main"}),+ ("fusion_take_screenshot", "Screenshot the Fusion window in the BACKGROUND (no focus steal, reads through occlusion). Use it to VERIFY your own work: geometry at the wrong Z, an empty view, or a Placeholder 3D body all render successfully and only a look at the pixels catches them.",+ {"outputPath": "optional str"}, {"success": "bool", "path": "str"}, 60, None, True, {}),+ ("fusion_verb_times", "This machine MEASURED timings per verb/stage - the same store that paces every progress bar and ETA. Read it to see whether an estimate is measured (this box has run it) or typical (still the seeded literal), and to explain a slow run.",+ {}, {"stages": "{name: {count, p50, p90}}"}, 15, None, True, {}), ("fusion_plan_library_import", "PRE-FLIGHT for a library import: does NO work and changes nothing. Reports whether Fusion is installed, running, or needs its add-in loaded (with a plain-language message you can show the user), plus a per-stage plan with MEASURED per-machine time estimates scaled to the number of parts you are sending - a multi-part library does one STEP import per part, which is the slowest stage, so the estimate grows with the library. Call this FIRST so the wiki can render the summary and the progress bar's steps, then run the import and poll fusion_prove_result, which reports the SAME stage names.", {"parts": "optional [{package, lbrPath, modelPath}] - the parts you intend to import (drives the estimate)", "stepPath": "optional single .step when not passing parts[]", "libraryPath": "optional .lbr for context"}, {"success": "bool", "fusion": "{installed, running, addinReady, status, message}", "plan": "[{stage, label, estimatedSec, confidence, needsUserConsent?}]", "estimatedSec": "float", "estimatedSecIfAlreadyOpen": "float", "summary": "str"},
page.json+7−10@@ -11,10 +11,6 @@ "uninstall": "./uninstall.sh" }, "tags": [- "ab",- "bridge",- "fusion",- "desktop-app", "fusion360", "autodesk", "cad",@@ -79,10 +75,7 @@ "build a basic parts library", "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"+ "set up the fusion bridge" ], "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.",@@ -111,5 +104,9 @@ "label": "Part volume", "prompt": "How much material does each printed part in this assembly use?" }- ]-}+ ],+ "author": {+ "name": "John Lauer",+ "email": "[email protected]"+ }+}
skills/fusion-libraries/SKILL.md+8@@ -111,3 +111,11 @@ Uploading models into the user's Fusion cloud is an outward, persistent action - - **Hand-built `shell_execute` quoting** - use `json.dumps`; escape Windows `\` as `\\` in the JSON. - **`desktop_screenshot_window` needs `hwnd`** (not `titleContains`); resolve it via `desktop_find_window` first. It returns the PNG as inline base64 - decode to a file. - **`adom-lbr validate` takes a positional `<PATH>`**, not `--lbr`.++## Importing a library end to end (web control, and the same verbs for you)++The full lane - pre-flight with measured ETAs, the four-artifact evidence bundle, per-part+3D binding, progress polling, and every failure contract that refuses rather than reporting+a false pass - is in **`fusion-web-control`**. Read it before importing a library or+rendering a progress bar for one. Note that the wiki's web control and you share ONE verb+surface: there is no verb only one side can call.
skills/fusion-multipart-libraries/SKILL.md+8@@ -221,3 +221,11 @@ Per part, hwnd-targeted (never fullscreen - see fusion-driving): the footprint a view with the real rendered chip on its footprint (the money shot), reopening the cloud library so the 3D preview refreshes. See [CREATING_BASIC_PARTS_LIBRARIES.md](../../CREATING_BASIC_PARTS_LIBRARIES.md) for the full tool-chain tutorial + montage recipe.++## Importing a library end to end (web control, and the same verbs for you)++The full lane - pre-flight with measured ETAs, the four-artifact evidence bundle, per-part+3D binding, progress polling, and every failure contract that refuses rather than reporting+a false pass - is in **`fusion-web-control`**. Read it before importing a library or+rendering a progress bar for one. Note that the wiki's web control and you share ONE verb+surface: there is no verb only one side can call.
skills/fusion-web-control/SKILL.mdadded+128@@ -0,0 +1,128 @@+---+name: fusion-web-control+description: >+ The library-import lane the wiki drives through Adom Bridge web control, and the same+ verbs an AI calls directly. Pre-flight planning with measured ETAs, the four-artifact+ evidence bundle, per-part 3D binding, progress polling, and every failure contract that+ now refuses rather than reporting a false pass. Read before importing a library into+ Fusion, before rendering a progress bar for one, or when a verb returns+ addin_restart_required, build_in_progress, blocked_by_dialog or no_evidence_captured.+ Trigger words - import a library into fusion, cloud libraries export, web control,+ fusion_create_library, fusion_plan_library_import, fusion_prove_result,+ fusion_build_library_3d, multi-part library, progress bar, ETA, evidence frames,+ addin_restart_required, restart fusion add-in, library import stuck.+discovery_triggers:+ - "import library into fusion"+ - "fusion web control"+ - "fusion_create_library"+ - "fusion_prove_result"+ - "addin_restart_required"+ - "library import progress"+---++# Driving a Fusion library import (web control, and the same verbs for you)++**There is ONE verb surface.** The wiki calling through Adom Bridge web control and you+calling `adom-bridge fusion_*` hit the same dispatcher. Anything web control can do, you+can do, with the same arguments and the same responses. There is no separate web-control+allowlist and no verb only one side can reach.++## The lane, in order++```+fusion_plan_library_import {parts} -> pre-flight: state + costed plan, NO work done+fusion_create_library {libraryPath, stepPath} -> one call: bind + prove, returns runId+ (or, for multi-part)+fusion_open_lbr {lbrPath} -> dialog-guarded; a bad .lbr FAILS+fusion_build_library_3d {lbrPath, parts[]} -> returns {runId, statusVerb}+fusion_prove_result {runId} -> poll: stage, percent, etaSec, evidence[]+```++`fusion_prove_result` is the single poll surface for **both** the create chain and the+detached 3D build. No second poll verb to learn.++## 1. Always pre-flight before you commit a user to anything++`fusion_plan_library_import {parts: [...]}` **does no work and changes nothing.** It answers+the four questions a caller needs before starting:++| `fusion.status` | What it means | What to do |+|---|---|---|+| `not_installed` | Fusion is not on this machine | Offer to install it; the plan includes the install stage (10-30 min) |+| `installed_not_running` | Just needs launching | Proceed; launch is a stage, ~60s, folded into the ETA |+| `addin_restart_required` | Running, but the add-in is not loaded | **Ask the user**, then `fusion_restart_for_addin` |+| `ready` | Good to go | Start |++It returns `plan[]` with a per-stage `estimatedSec` and `confidence`, plus `estimatedSec`+and `estimatedSecIfAlreadyOpen`. **The bind estimate scales with the part count** — a+multi-part library does one STEP import per part, which is the slowest stage — so a 7-part+bundle is costed as 7, not as 1.++`confidence: "measured"` means this machine has actually run that stage before and the+number is its own p50. `"typical"` means it is still the seeded literal. Say which, if you+show the user a time.++## 2. The add-in restart contract (the one that burned a real user)++A new user installed ab with **Fusion already open**. The bridge wrote a fresh add-in;+Fusion loads add-ins only at launch, so the running Fusion could not see it, and every verb+failed with a bare "add-in not responding". He had no way to know the product was fine and+merely needed a relaunch.++Any verb needing the add-in now returns:++```json+{ "errorCode": "addin_restart_required", "restartRequired": true,+ "userMessage": "Fusion needs a quick restart to finish setting up the Adom add-in.+ We can save your open documents first.",+ "documentsKnown": true, "openDocuments": 3, "unsavedDocuments": 2,+ "remedyVerb": "fusion_restart_for_addin" }+```++- **Show `userMessage`.** An ab toast also fires, so the human is told even if you drop the payload.+- **Branch on `documentsKnown`.** The counts come from the add-in, which by definition is not answering; when it cannot be reached they are `null` rather than guessed.+- **Ask before restarting when a human is present.** Then `fusion_restart_for_addin {save:true}`, which saves first and **refuses** with `unsaved_named_document` rather than discarding a never-saved document.++## 3. Reading progress honestly++`fusion_prove_result` gives `stage`, `stageLabel`, `plan[]`, `stagesDone`, `percent`,+`etaSec`, `confidence`, and `evidence[]` that fills in **as each artifact lands**, in+assembly order: **symbol → footprint → 3d → ganged**. The ganged view is last by design, as+the closing proof. A 3D build additionally reports `minting <part> (3/7)`, `partsDone`,+`partsTotal` and `parts[]` with each `wip_urn`.++**`stage: "done"` does NOT mean it worked.** It means the chain finished. The score is the+top-level `verdict` (`proven` / `not_proven`). For a multi-part build, `done` means the run+completed, not that every part bound — **check `parts[]` for any `success: false`** before+telling a user their library is complete.++## 4. Failure contracts — these refuse instead of lying++Every one of these exists because it once reported success and someone believed it.++| errorCode | Meaning | Response |+|---|---|---|+| `no_evidence_captured` | The chain finished with ZERO frames | Not a success. Investigate |+| `blocked_by_dialog` | A blocking dialog was up; **`dialogText` carries what Fusion is showing** | Show the text; clear the condition |+| `build_in_progress` | A 3D build is still running, so a capture would photograph the build editor | Wait, then re-capture |+| `wrong_editor_captured` | A frame was taken outside the Electronics Library editor | The frame does not show what it claims |+| `no_3d_package_bound` | No `<package3d>`, so the only thing to photograph is a grey Placeholder | Bind 3D first |+| `unsaved_named_document` | A never-saved document cannot be closed silently | Save with an explicit destination first |+| `no_path_argument` | No library path given; **the file was never examined** | Do not re-stage the file; fix the argument |+| `artifact_not_in_library` | The name is not in the `.lbr`, so no EDIT was issued | Pick from `available[]` |++**The doctrine behind the whole table:** a non-result reported as success is the worst+failure an evidence pipeline can have, because it is the one nobody re-checks. Prefer a+refusal that names the cause.++## 5. Arguments are forgiving; paths are Windows-local++`fusion_open_lbr` accepts `filePath`, `lbrPath`, `libraryPath` or `path` — you should never+have to guess our spelling. Paths must be **Windows-local** (`C:/...`): the bridge runs on+the user's machine, and a container path means nothing to it.++## 6. Never let Fusion draw a dialog++A modal freezes the add-in's single main thread, so the bridge stops answering and every+later verb reads as a crash. See the **fusion-no-modal-dialogs** skill. Short version:+prove a command unnecessary offline, or pre-answer it — never issue one and plan to sweep up.