← Commit history
BRIDGE_VERSION+1−1
@@ -1 +1 @@-1.10.31\ No newline at end of file+1.10.32\ 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.31",+  "version": "1.10.32",   "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+2−2
@@ -288,7 +288,7 @@         "success": "bool"       },       "statusVerb": null,-      "summary": "Set the org's APS (PKCE) client id used for cloud search.",+      "summary": "Set the org's APS (PKCE) client id used for cloud search. Get it from your org's members-only wiki page: adom-wiki api /api/v1/pages/<org>/org-settings/files/integrations/autodesk-aps.json (never from another machine's config file). The reply carries orgSettingsFile, the exact JSON to publish there when your org has none yet, so every other box adopts it in two calls (fusion-aps-org-setup skill). Public identifier, no secret.",       "timeoutSeconds": 20     },     {@@ -322,7 +322,7 @@         "signedIn": "bool"       },       "statusVerb": null,-      "summary": "APS state: configured, signed in, token live, never-charge meter.",+      "summary": "APS state: configured, signed in, token live, never-charge meter. When configured:false the hint sends you to your org's shared app ID on the wiki (<org>/org-settings, integrations/autodesk-aps.json) before anything else; the fusion-aps-org-setup skill covers new boxes and first-time orgs.",       "timeoutSeconds": 20     },     {
dashboard/Cargo.lock+1−1
@@ -4,7 +4,7 @@ version = 4  [[package]] name = "fusion-dashboard"-version = "1.10.31"+version = "1.10.32" dependencies = [  "serde_json", ]
dashboard/Cargo.toml+1−1
@@ -1,6 +1,6 @@ [package] name = "fusion-dashboard"-version = "1.10.31"+version = "1.10.32" edition = "2021"  [dependencies]
describe.py+2−2
@@ -92,9 +92,9 @@ _T = [      240, "fusion_demo", True, {}),      # ── Cloud search & files (APS) ─────────────────────────────────────────-    ("fusion_aps_status", "APS state: configured, signed in, token live, never-charge meter.",+    ("fusion_aps_status", "APS state: configured, signed in, token live, never-charge meter. When configured:false the hint sends you to your org's shared app ID on the wiki (<org>/org-settings, integrations/autodesk-aps.json) before anything else; the fusion-aps-org-setup skill covers new boxes and first-time orgs.",      {}, {"configured": "bool", "signedIn": "bool", "neverCharge": "bool"}, 20, None, False, {}),-    ("fusion_aps_set_client_id", "Set the org's APS (PKCE) client id used for cloud search.",+    ("fusion_aps_set_client_id", "Set the org's APS (PKCE) client id used for cloud search. Get it from your org's members-only wiki page: adom-wiki api /api/v1/pages/<org>/org-settings/files/integrations/autodesk-aps.json (never from another machine's config file). The reply carries orgSettingsFile, the exact JSON to publish there when your org has none yet, so every other box adopts it in two calls (fusion-aps-org-setup skill). Public identifier, no secret.",      {"clientId": "required str"}, {"success": "bool"}, 20, None, False, {"clientId": "D5nn...EPAq"}),     ("fusion_aps_signin", "Open the Autodesk sign-in in the REMEMBERED browser+profile (not the OS default); a background listener captures the token. Pass {exe,profileDir,name} to use+remember a specific browser, or {allowDefaultBrowser:true} to fall back to the OS default. If nothing is remembered, returns needsExtensionOpen so the caller opens authUrl in the user's real browser via nbrowser_open_window.",      {"exe": "optional str (browser binary to launch+remember)", "profileDir": "optional str (e.g. 'Default','Profile 2')", "name": "optional str", "allowDefaultBrowser": "optional bool"},
docs/aps-cloud-search.md+11−2
@@ -46,8 +46,17 @@ adom-bridge fusion_aps_set_client_id '{"clientId":"..."}'           # once per c adom-bridge fusion_aps_signin '{"profile":"chrome:[email protected]"}'   # once per user ``` -Register a Desktop/PKCE app at [aps.autodesk.com](https://aps.autodesk.com) with the Data-Management API enabled and the callbacks the status verb lists. Only the Client ID is stored; the+The Client ID is per org and lives on the wiki, on the members-only `<org>/org-settings` page:++```bash+adom-wiki api /api/v1/pages/<org>/org-settings/files/integrations/autodesk-aps.json   # -> { "clientId": ... }+```++A new box adopts it from there, and the person then signs in with their own Autodesk login. A 404 means+your org has not published one: one admin registers a Desktop/PKCE app at+[aps.autodesk.com](https://aps.autodesk.com) with the Data Management API enabled and the callbacks the+status verb lists, sets it, and publishes it (`fusion_aps_set_client_id` returns the exact file). The+`fusion-aps-org-setup` skill has every step. No Client ID is baked into the bridge. Only the Client ID is stored; the bridge runs its own PKCE OAuth with no client secret.  **Sign-in is usually silent.** If your browser profile already holds an Autodesk session, consent
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.31"+DASH_VERSION="1.10.32" 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+6−2
@@ -1,6 +1,6 @@ {   "slug": "fusion-bridge",-  "version": "1.10.31",+  "version": "1.10.32",   "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": {@@ -38,7 +38,11 @@     "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",+    "aps not configured",+    "share aps client id across my org",+    "set up fusion cloud search for my company",+    "org settings autodesk aps"   ],   "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).",   "sample_prompts": [
page.json+15−27
@@ -1,6 +1,6 @@ {   "slug": "fusion-bridge",-  "version": "1.10.31",+  "version": "1.10.32",   "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,14 @@     "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",+    "aps not configured",+    "share aps client id across my org",+    "set up fusion cloud search for my company",+    "org settings autodesk aps"   ],   "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 +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]"-  }-}\ 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.31"+version = "1.10.32" edition = "2021" license = "MIT" 
rust/bridge/src/aps_signin.rs+13−3
@@ -92,7 +92,14 @@ fn open_os_window_extension_free(ctx: &Ctx, url: &str, profile: Option<&str>) ->     if let Some(p) = &profile { a["profile"] = json!(p); }     let mut r = ab_call(ctx, "nbrowser_open_window", a.clone(), 60);     let owned = r["_adCallError"].is_null() && (r["ok"].as_bool() == Some(true) || !r["sessionId"].is_null());-    if !owned { r = ab_call(ctx, "nbrowser_open_os_window", a.clone(), 60); }+    if !owned {+        // Nobody can drive this window (no extension), so a HUMAN has to click in it: it must be+        // on screen. Opened "background" it was parked at -32000,-32000 and John could not find it+        // on either monitor (arav-rog, 2026-09-20). Open it visible and pull it onto the primary.+        a["background"] = json!(false);+        r = ab_call(ctx, "nbrowser_open_os_window", a.clone(), 60);+        if let Some(h) = r["hwnd"].as_i64() { let _ = ab_call(ctx, "desktop_set_window_bounds", json!({"hwnd": h, "x": 80, "y": 60, "w": 1200, "h": 900, "reason": "the Autodesk consent page needs the user to click in it, so it has to be on screen"}), 15); }+    }     if !r["_adCallError"].is_null() { return json!({"launched": false, "profile": profile, "error": r["_adCallError"]}); }     let launched = r["ok"].as_bool() == Some(true) || !r["hwnd"].is_null() || !r["sessionId"].is_null() || r["_hint"].as_str().unwrap_or("").contains("Launch fired");     if launched { crate::signin::track_signin_window(&sess, profile.as_deref().unwrap_or(""), "aps"); }@@ -146,7 +153,8 @@ pub fn signin(ctx: &Ctx, args: &Value) -> Value {     let store = ApsStore::default_location();     let client_id = store.client_id();     if client_id.is_empty() {-        return json!({"success": false, "error": "No APS Client ID configured.", "errorCode": "aps_not_configured", "_hint": format!("Call fusion_aps_set_client_id {{\"clientId\":\"...\"}} first (register a Desktop/PKCE app at https://aps.autodesk.com with Data Management API + callbacks {}).", all_registered_callbacks().join(", "))});+        return json!({"success": false, "error": "No APS Client ID configured.", "errorCode": "aps_not_configured", "orgSettingsPath": "/api/v1/pages/<org>/org-settings/files/integrations/autodesk-aps.json",+            "_hint": format!("No APS app ID on this box. FIRST check your org's shared settings on the wiki (members-only, no secret involved): `adom-wiki whoami` names your org, then `adom-wiki api /api/v1/pages/<org>/org-settings/files/integrations/autodesk-aps.json` returns {{clientId}}. Got one: fusion_aps_set_client_id {{\"clientId\":\"<it>\"}} then fusion_aps_signin, and the person signs in with THEIR OWN Autodesk login. 404 (your org has none yet, or you work solo): one admin registers a Desktop/PKCE app ONCE at https://aps.autodesk.com (Data Management API, the callbacks below), sets it here, and publishes it to <org>/org-settings so nobody in the org ever does this again (the fusion-aps-org-setup skill has the exact file and commands). Do NOT read another machine's config files for it. Callbacks: {}.", all_registered_callbacks().join(", "))});     }     let (verifier, challenge) = pkce_pair();     let mut sb = [0u8; 12]; let _ = getrandom::getrandom(&mut sb); let state = b64url(&sb);@@ -199,7 +207,9 @@ pub fn set_client_id(args: &Value) -> Value {     let store = ApsStore::default_location();     let mut cfg = store.read("config.json"); if !cfg.is_object() { cfg = json!({}); }     cfg["client_id"] = json!(cid); store.write("config.json", &cfg);-    json!({"success": true, "output": format!("Saved APS Client ID ({}...). Now call fusion_aps_signin.", cid.chars().take(6).collect::<String>()), "data": {"configured": true}})+    json!({"success": true, "output": format!("Saved APS Client ID ({}...). Now call fusion_aps_signin.", cid.chars().take(6).collect::<String>()), "data": {"configured": true},+        "orgSettingsFile": {"path": "integrations/autodesk-aps.json", "content": {"schema": "adom.org-integration/1", "integration": "autodesk-aps", "owner": "<org>", "clientId": cid, "kind": "public-pkce-client-id", "secret": false}},+        "_hint": "Saved. NEXT: fusion_aps_signin. THEN share it so no other box in your org needs this step: if `adom-wiki api /api/v1/pages/<org>/org-settings/files/integrations/autodesk-aps.json` is a 404, save orgSettingsFile.content (with your org slug as owner) to integrations/autodesk-aps.json and `adom-wiki repo push <org>/org-settings --files integrations/autodesk-aps.json` (create the page first, private, with `adom-wiki page create org-settings --org <org> --private --type skill ...`). It is a public PKCE identifier, never a secret. The fusion-aps-org-setup skill walks through it."}) } pub fn set_browser(args: &Value) -> Value {     let store = ApsStore::default_location();
rust/bridge/src/main.rs+1−1
@@ -1181,7 +1181,7 @@ fn native_aps_status(sidecar: &Arc<Mutex<Option<Sidecar>>>, caller: &Caller) ->         "freeEndpointsOnly": FREE_PATH_PREFIXES, "neverCharge": true,     });     let (hint, summary) = if client_id.is_empty() {-        (format!("Not configured. Register a Desktop/PKCE app at https://aps.autodesk.com (enable Data Management API, set callbacks {}), then fusion_aps_set_client_id {{\"clientId\":\"...\"}} and fusion_aps_signin.", all_registered_callbacks().join(", ")), "APS not configured")+        (format!("Not configured: this box has no APS app ID. FIRST look in your org's shared settings on the wiki (members-only, nothing secret): `adom-wiki whoami` names your org, then `adom-wiki api /api/v1/pages/<org>/org-settings/files/integrations/autodesk-aps.json` returns {{clientId}}. Got one: fusion_aps_set_client_id {{\"clientId\":\"<it>\"}} then fusion_aps_signin (the person signs in with their OWN Autodesk login). 404: one admin registers a Desktop/PKCE app ONCE at https://aps.autodesk.com (enable Data Management API, set callbacks {}), sets it here, and publishes it to <org>/org-settings so the rest of the org never repeats this (fusion-aps-org-setup skill). Do NOT read another machine's config files for it.", all_registered_callbacks().join(", ")), "APS not configured")     } else if !has_at { ("Configured but not signed in. Call fusion_aps_signin (opens browser).".into(), "configured, not signed in") }     else if !live { ("Token expired and refresh failed. Call fusion_aps_signin again.".into(), "signed in, token expired") }     else { ("Ready. Use fusion_aps_search {\"query\":\"...\"}.".into(), "ready") };
skills/fusion-aps-org-setup/SKILL.mdadded+76
@@ -0,0 +1,76 @@+---+name: fusion-aps-org-setup+description: How an ORG (or a solo user) gets Fusion cloud search (APS) working on every box with one admin setup - where the org's APS app ID lives (the members-only <org>/org-settings wiki page), how a new box adopts it in two calls, how the first admin registers the Autodesk app and publishes the ID for everyone else, and what each person still does themselves (one Autodesk sign-in). Read this whenever fusion_aps_status says configured:false, before telling anyone to register an APS app, and before copying an ID between machines. Trigger words - aps not configured, aps_not_configured, fusion_aps_set_client_id, APS client id, share aps id, org settings, org-settings, autodesk-aps.json, set up aps for my company, aps first time setup, new box aps, cloud search not set up, consent window not visible.+---++# APS for a whole org: one admin setup, then everyone just signs in++Parent skill: **fusion-aps-search** (what APS is, quotas, search verbs). Sign-in driving: **fusion-aps-signin**.++## The model in four sentences++Fusion cloud search uses Autodesk Platform Services (APS) with PKCE, so there is NO secret and no server: only a public **app ID** (Client ID) plus each person's own Autodesk sign-in. The app ID is **per org**: one admin registers one Autodesk app, once. It lives on the wiki at **`<org>/org-settings`**, a private page only org members can read, in `integrations/autodesk-aps.json`. A new box adopts it in two calls, and the person signs in as themselves.++## A. New box, org already set up (the common case, about a minute)++```bash+adom-wiki whoami                                   # "orgs": your org slug, e.g. adom+adom-wiki api /api/v1/pages/<org>/org-settings/files/integrations/autodesk-aps.json+#   -> { "clientId": "...", "secret": false, ... }      404 = go to section B+adom-bridge --target <box> fusion_aps_set_client_id '{"clientId":"<clientId>"}'+adom-bridge --target <box> fusion_aps_signin '{}'+adom-bridge --target <box> fusion_aps_status '{}'  # poll until signedIn:true+```++- The wiki read uses YOUR wiki token inside the container. The desktop box never needs a wiki token.+- Sign-in opens a browser window on the box. With a warm Autodesk session it completes by itself. Otherwise the person signs in there: never type their password or 2FA code for them.+- Since 1.10.32 a consent window that needs a human is opened VISIBLE on the primary monitor. On older bridges it could be parked off-screen at -32000: `desktop_list_windows`, find "Sign in - Autodesk", then `desktop_set_window_bounds {hwnd,x,y,w,h}` and `desktop_bring_to_front {hwnd, reason}`.+- Whose Autodesk login? The same account Fusion uses on that box is the natural choice: search then sees exactly what that person sees in Fusion.++**Never** read another machine's `~/.adom/fusion-aps/config.json` to find the ID. It looks like credential hunting, permission systems block it, and the wiki page exists so you do not have to.++## B. First time for this org (one admin, once)++1. At [aps.autodesk.com](https://aps.autodesk.com): sign in, accept the Free plan, create a developer hub if asked, create an app of type **Desktop, Mobile, Single-Page App** (PKCE).+2. Enable the **Data Management API** on the app. Without it sign-in fails with AUTH-001 before any login.+3. Add every callback `fusion_aps_status` lists (six localhost URLs on ports 8917, 8918, 8920).+4. Copy the Client ID. `fusion_aps_set_client_id {clientId}`, then `fusion_aps_signin`.+5. **Publish it for the org** so nobody repeats steps 1 to 4. `fusion_aps_set_client_id` returns `orgSettingsFile.content` ready to save:++```bash+adom-wiki page create org-settings --org <org> --private --type skill \+  --title "<Org> Org Settings" \+  --brief "Shared, non-secret integration IDs for <org>, read by every member's AI." \+  --because "No page holds org-wide integration IDs; brand is a visual guide with its own confirm gate." \+  --headline "One sign-in, every box" \+  --subhead "Your org's shared integration IDs, read by your AI so nobody copies config between machines"+adom-wiki repo clone <org>/org-settings && cd org-settings+mkdir -p integrations    # save orgSettingsFile.content here, owner = your org slug:+#   integrations/autodesk-aps.json+adom-wiki repo push <org>/org-settings --files integrations/autodesk-aps.json -m "APS app id for the org"+```++A solo user does the same under their own username instead of `--org`.++## The file++```json+{+  "schema": "adom.org-integration/1",+  "integration": "autodesk-aps",+  "owner": "<org slug>",+  "clientId": "<public app id>",+  "kind": "public-pkce-client-id",+  "secret": false+}+```++`secret` is always `false` in this repo. Real secrets go in page secrets (`adom-wiki secret`), which are write-only.++## What each person still does themselves++One Autodesk sign-in per box, in the browser window the bridge opens. Tokens are per person and per box and are never shared or published. Refresh is automatic; a box that was offline long enough for the refresh token to lapse just runs `fusion_aps_signin` again.++## Status of the standard++`<org>/org-settings` is a convention the Fusion bridge uses today. A first-class org-default settings repo (auto-created beside `<org>/brand`, with CLI sugar) is proposed in [adom/adom-wiki-cli issue 59](https://wiki.adom.inc/adom/adom-wiki-cli/issues/59). If that lands with a different name or path, the bridge hints and this skill move with it.
skills/fusion-aps-search/SKILL.md+8−6
@@ -73,8 +73,9 @@ The unit of setup is the **organization/company**, NOT the whole Adom platform:     and folders. So search hits the real shared team files regardless of which dev hub the app     lives in. (Almost every Adom user already shares an Autodesk cloud hub — search "just     works" against it once they sign in.)-- Net: admin does plan→dev-hub→app→Client-ID ONCE; ship the Client ID as the bridge default;-  every user does one `fusion_aps_signin` and searches the shared team files fast.+- Net: admin does plan→dev-hub→app→Client-ID ONCE and publishes it to the members-only `<org>/org-settings`+  wiki page (fusion-aps-org-setup skill); every box adopts it from there, and every user does one+  `fusion_aps_signin`. There is NO Client ID baked into the bridge.  ## Ecosystem + automation requirement - Must work for **ALL Adom users**, not just John.@@ -104,10 +105,11 @@ minutes, times out, blocks every other script, and locks Fusion up**. It is depr for cloud search, ever — no matter how blocked you feel.  **Auto-recover APS (do this instead of giving up):**-1. **Not configured?** The org Client ID is a **public PKCE identifier** (no secret) — pull it from a-   peer that already has it: `adom-bridge status` lists connected desktops; read-   `~/.adom/fusion-aps/config.json` (key `client_id`) off one via `shell_execute`/`pull_file`, then-   `fusion_aps_set_client_id {clientId}`.+1. **Not configured?** The org Client ID is a **public PKCE identifier** (no secret) and lives on the+   wiki: `adom-wiki api /api/v1/pages/<org>/org-settings/files/integrations/autodesk-aps.json` (your org+   from `adom-wiki whoami`), then `fusion_aps_set_client_id {clientId}`. A 404 means the org has not+   published one: the **fusion-aps-org-setup** skill covers the one-time admin setup and publishing it.+   Do NOT read another machine's config file for it. 2. **Sign in:** `fusion_aps_signin` → open the returned `authUrl` in the user's REAL browser with a warm    Autodesk session. **Install + use the adom-browser-extension (nbrowser/ABE) to drive the browser**    ([wiki](https://wiki.adom.inc/adom/adom-browser-extension)) — coordinate/keyboard-clicking a browser
tools/check-naming.sh

  
tools/check-portable.sh

  
tools/promote.sh

  
tools/release.sh