← Commit history

0.31.0: physical_properties, preferences, select_items, cancel_run join (#29); proposals may carry the platform tier

Colby Knox ·e3abbdb98a ·5d ago ·parent cd059d5
6 files changed +210−15
README.md+4−3
@@ -61,11 +61,11 @@ verb by verb: [docs/coverage.md](docs/coverage.md). | Tier | Verbs | Altium | KiCad | Fusion 360 | |---|---|---|---|---| | **core** | 95 | 95 | 95 | 93 |-| **native** | 53 | 53 | 53 | 50 |+| **native** | 54 | 53 | 53 | 51 | | **checks** | 38 | 38 | 38 | 38 |-| **app** | 66 | 66 | 55 | 58 |+| **app** | 69 | 66 | 56 | 61 | | **platform** | 18 | 18 | 0 | 1 |-| standard (all but platform) | 252 | 252 | 241 | 239 |+| standard (all but platform) | 256 | 252 | 242 | 243 | <!-- coverage:end -->  The **checks** tier is where the other bridges are furthest behind, and it is the cheapest to close: those verbs are@@ -158,6 +158,7 @@ Decisions so far (proposals from the KiCad and Fusion bridges, 2026-10-27; issue  ## Status +Version 0.31.0: physical_properties, preferences, select_items and cancel_run join from Fusion (#29), 256 verbs; proposals may now carry the platform tier. Version 0.30.14: coverage reads Fusion 360 bridge 1.13.55 (sch_place_part, sch_swap_part and edit_parts exact). Version 0.30.13: coverage reads Fusion 360 bridge 1.13.52 (public; urgent fix for fusion-bridge#136, no verb changes). Version 0.30.12: coverage reads Fusion 360 bridge 1.13.49 (public; urgent fix for fusion-bridge#136, no verb changes).
docs/coverage.md+8−4
@@ -1,17 +1,17 @@ # Coverage: every standard verb on each bridge -Altium bridge 0.2.88 (the reference), KiCad bridge 1.0.98, Fusion 360 bridge 1.13.55. 67 verbs came from other bridges' proposals (tools/proposed/); they are marked *proposed*.+Altium bridge 0.2.88 (the reference), KiCad bridge 1.0.98, Fusion 360 bridge 1.13.55. 71 verbs came from other bridges' proposals (tools/proposed/); they are marked *proposed*. `exact` is the same job under the same or an equivalent name; `partial` does part of it or does it differently (`verbs/coverage.json` names what in `note`); `unsupported` answers `not_supported` for the whole job and is not counted; blank is missing. Generated by `tools/generate.py` from `verbs/coverage.json`; do not edit by hand.  | Tier | Verbs | Altium | KiCad | Fusion 360 | |---|---|---|---|---| | **core** | 95 | 95 | 95 | 93 |-| **native** | 53 | 53 | 53 | 50 |+| **native** | 54 | 53 | 53 | 51 | | **checks** | 38 | 38 | 38 | 38 |-| **app** | 66 | 66 | 55 | 58 |+| **app** | 69 | 66 | 56 | 61 | | **platform** | 18 | 18 | 0 | 1 |-| standard (all but platform) | 252 | 252 | 241 | 239 |+| standard (all but platform) | 256 | 252 | 242 | 243 |  ## core @@ -154,6 +154,7 @@ Wraps the EDA tool's own feature (its DRC, ERC, Gerbers, pours, Update PCB). Eve | `netlist` | The compiled netlist of a project: every net with its pins (Designator.Pin) across every sheet, the hierarchy resolved; or one net; or compare with the nets... | `altium_netlist` | `kicad_netlist` | `fusion_netlist` | | `panelize` | Step and repeat a board into a manufacturing panel: a new .PcbDoc holding Altium's own embedded board array of the board (rows x cols), with rails, the... | `altium_panelize` | `kicad_panelize` (partial) | `fusion_panelize` | | `pcb_report` | Numbers instead of pixels: for a PcbLib, every footprint's pads, pad bounding box, primitive census and 3D bodies; for a board, outline, components with... | `altium_pcb_report` | `kicad_errors` (partial) | `fusion_pcb_report` |+| `physical_properties` *proposed* | Per component: volume, mass, density, surface area and centre of mass, from the tool's own materials. A tool with no materials or part masses answers... |  |  | `fusion_physical_properties` | | `pour_state` | Every polygon pour with the copper it actually poured: filled area per pour and per layer, and the pours that poured nothing. | `altium_pour_state` | `kicad_pour_state` | `fusion_pour_state` | | `project_snapshot` *proposed* | A dated copy of the project's documents into <project>/snapshots/<stamp>[-label]/, with PDFs of the schematic and the board made by the tool. | `altium_project_snapshot` | `kicad_project_snapshot` | `fusion_project_snapshot` (partial) | | `remove_pours` | Delete polygon pours by net (and layer), or all of them, and the pour keepouts (cutouts) apply_pours made. Tracks and vias are untouched. | `altium_remove_pours` | `kicad_remove_zone` | `fusion_remove_pours` |@@ -232,6 +233,7 @@ Driving the application itself (launch, licence, dialogs, windows, views). Each | `agent_status` | Is the agent loop alive and responsive, in which workspace, and is any loop resident anywhere? Read-only; never starts the agent. | `altium_agent_status` | unsupported | `fusion_addin_status` (partial) | | `agent_stop` | Stop the selected instance's resident agent loop (drops a stop file and waits up to 12 s for the heartbeat to go stale). | `altium_agent_stop` | unsupported | unsupported | | `animate_view` | Camera/zoom choreography on the current document - native Altium camera commands, animated by Altium itself. | `altium_animate_view` | `kicad_animate_view` | `fusion_view` (partial) |+| `cancel_run` *proposed* | Stop the bridge's own long job, between steps, keeping what is done. With nothing to stop it answers cancelRequested:false and a reason. It never claims to... |  |  | `fusion_cancel_run` (partial) | | `check_dialogs` | List every Altium dialog currently open, classified, each with a screenshot (the only way to READ one: Altium paints its dialog text). | `altium_check_dialogs` | `kicad_state / kicad_dismiss_dialogs` (partial) | `fusion_check_dialogs` | | `close` | Polite close (releases the licence seat). Frees a script engine parked on a breakpoint first (Altium refuses to close over one). discardChanges:true answers... | `altium_close` | `kicad_close` | `fusion_stop` | | `close_all_documents` *proposed* | Close every open document without a save dialog. Unsaved work is never lost by default: a document with unsaved changes stays open and is listed, unless... | `altium_close_all_documents` | `kicad_close` (partial) | `fusion_close_all_documents` |@@ -262,6 +264,7 @@ Driving the application itself (launch, licence, dialogs, windows, views). Each | `open_document` | Open a document or project by path through the agent and show it without focusing it. An already-open document is activated, not reloaded. | `altium_open_document` | `kicad_open_document` | `fusion_open_document` | | `open_project` | Open a project (.PrjPcb / .PrjScr / .PrjMbd / .PrjHar / .LibPkg) by path. Same handler as altium_open_document. | `altium_open_project` | `kicad_open_project` | `fusion_open_cloud_file` (partial) | | `panel` | Activate a docked panel TAB (SCH Library, PCB Library, Components, Projects, Properties) in the BACKGROUND - the 'ganged-up view' needs the right panels in... | `altium_panel` | `kicad_send_key` (partial) | `fusion_panel` |+| `preferences` *proposed* | Read the tool's own settings (all, or one by key), or change them with set. Reports per key what was applied. A tool that rewrites its settings on exit... |  |  | `fusion_preferences` | | `prewarm` *proposed* | Get this machine ready for a fast first call: detect the tool, seed its first-run settings, dismiss first-run wizards and repair what the first real call... | `altium_prewarm` | `kicad_prewarm` | `fusion_prewarm` | | `progress` | The bridge's timing book: phases in flight right now (percent/ETA blocks ab paints on the taskbar), measured phase history and per-verb run statistics. | `altium_progress` | `kicad_progress` | `fusion_progress` | | `readiness` | The one-call gate: is Altium installed, running, licensed, and is the resident agent alive? Answers with Altium closed and never touches the script engine. | `altium_readiness` | `kicad_readiness` | `fusion_readiness` |@@ -269,6 +272,7 @@ Driving the application itself (launch, licence, dialogs, windows, views). Each | `run_script` | One shot: run a procedure of YOUR OWN .PrjScr through Altium's -R command line. Only for when the agent is NOT resident. | `altium_run_script` | `kicad_run_script` | `fusion_run_script` | | `save` | Save the focused document, or the document at filePath (opened first if need be, saved by its path, never whatever happens to have focus). | `altium_save` | `kicad_save` (partial) | `fusion_save` | | `sch_zoom` | Find parts on a sheet: select them (everything else deselected), frame the view on them and return a proof frame. The schematic half of cross-probing (the... | `altium_sch_zoom` | `kicad_sch_zoom` (partial) | `fusion_sch_zoom` |+| `select_items` *proposed* | Select parts by designator on the board or the sheet, or clear the selection. A bridge that cannot select on one of them refuses it by name. verified says... |  | `kicad_select_items` | `fusion_select_items` (partial) | | `select_net` | Select one net as a whole on the current board (tracks, arcs, vias, pads, pours) and nothing else, optionally framing it; no net clears the selection. | `altium_select_net` | `kicad_select_net` | `fusion_select_net` | | `selection` | What the user has selected in the current board (components with position mm, rotation, side, footprint, size) or sheet (components with location mils and... | `altium_selection` | `kicad_selection` (partial) | unsupported | | `selftest_script_error` | Regression test for the script-error safety net (from 0.2.23): makes the agent raise a REAL DelphiScript runtime error on purpose and checks that the bridge... | `altium_selftest_script_error` | unsupported | unsupported |
package.json+1−1
@@ -1,6 +1,6 @@ {   "slug": "eda-bridge-standard",-  "version": "0.30.14",+  "version": "0.31.0",   "type": "skill",   "title": "EDA Bridge Standard: one way for an AI to drive every PCB tool",   "description": "The standard every Adom EDA bridge follows so one AI can drive Altium, KiCad, Fusion 360 and any future PCB tool the same way: shared verb names in tiers, the board model JSON, reply and refusal conventions, and a coverage table of each bridge against the Altium reference.",
tools/generate.py+2−2
@@ -62,8 +62,8 @@ def proposals(tiered):                 continue             if p["proposedBy"] != thread:                 problems.append(f"{name}: proposedBy {p['proposedBy']!r} but filed in tools/proposed/{thread}.json")-            if p["tier"] not in ORDER or p["tier"] == "platform":-                problems.append(f"{name}: tier {p['tier']!r} is not one of core, native, checks, app")+            if p["tier"] not in ORDER:+                problems.append(f"{name}: tier {p['tier']!r} is not one of core, native, checks, app, platform")             if not [t for t in p["agreedBy"] if t != p["proposedBy"]]:                 problems.append(f"{name}: agreedBy names no thread other than its proposer ({p['proposedBy']})")             # a tiered Altium verb was in the standard first; an untiered one of the same name is Altium implementing this
verbs/coverage.json+53−3
@@ -1,10 +1,10 @@ {- "standard": "0.30.14",+ "standard": "0.31.0",  "reference": {   "bridge": "altium",   "version": "0.2.88"  },- "proposed": 67,+ "proposed": 71,  "compared": {   "kicad": "1.0.98",   "fusion360": "1.13.55"@@ -2246,6 +2246,17 @@     "match": "exact"    }   },+  {+   "name": "physical_properties",+   "tier": "native",+   "source": "proposed",+   "altium": null,+   "kicad": null,+   "fusion360": {+    "verb": "fusion_physical_properties",+    "match": "exact"+   }+  },   {    "name": "pour_state",    "tier": "native",@@ -3363,6 +3374,18 @@     "note": "Fusion's own camera with smooth transitions (fit, home, iso, orbit, zoom, pan) on the 3D view; the 2D board and schematic zoom with fusion_electron_zoom"    }   },+  {+   "name": "cancel_run",+   "tier": "app",+   "source": "proposed",+   "altium": null,+   "kicad": null,+   "fusion360": {+    "verb": "fusion_cancel_run",+    "match": "partial",+    "note": "library imports (fusion_create_library, fusion_install_library_bundle): the only long jobs that stop between steps"+   }+  },   {    "name": "check_dialogs",    "tier": "app",@@ -3789,7 +3812,7 @@    "fusion360": {     "verb": "fusion_account",     "match": "partial",-    "note": "Fusion is licensed through the Autodesk account: the signed-in account, Autodesk's licence state and whether this machine holds the seat (there is no licence page to drive)"+    "note": "Fusion is licensed through the Autodesk account: the signed-in account, Autodesk's licence state and whether this machine holds the seat, with use_license and release moving the seat (fusion_claim_seat, fusion_release_seat); there is no licence page to drive"    }   },   {@@ -3897,6 +3920,18 @@     "match": "exact"    }   },+  {+   "name": "preferences",+   "tier": "app",+   "source": "proposed",+   "altium": null,+   "kicad": null,+   "fusion360": {+    "verb": "fusion_preferences",+    "match": "exact",+    "note": "Fusion's appearance and navigation settings, applied live with no restart"+   }+  },   {    "name": "prewarm",    "tier": "app",@@ -4020,6 +4055,21 @@     "match": "exact"    }   },+  {+   "name": "select_items",+   "tier": "app",+   "source": "proposed",+   "altium": null,+   "kicad": {+    "verb": "kicad_select_items",+    "match": "exact"+   },+   "fusion360": {+    "verb": "fusion_select_items",+    "match": "partial",+    "note": "parts by designator in the editor in front, or in the one where names; verified is always false, since Fusion does not report its electronics selection back"+   }+  },   {    "name": "select_net",    "tier": "app",
verbs/standard.json+142−2
@@ -1,10 +1,10 @@ {- "standard": "0.30.14",+ "standard": "0.31.0",  "reference": {   "bridge": "altium",   "version": "0.2.88"  },- "proposed": 67,+ "proposed": 71,  "compared": {   "kicad": "1.0.98",   "fusion360": "1.13.55"@@ -5019,6 +5019,41 @@    "timeoutSeconds": 60,    "unitsNote": "The reference bridge answers this verb in mils (xMil). A bridge following the standard answers in mm under Mm names (xMm)."   },+  {+   "name": "physical_properties",+   "tier": "native",+   "source": "proposed",+   "summary": "Per component: volume, mass, density, surface area and centre of mass, from the tool's own materials. A tool with no materials or part masses answers unsupported with the reason. Read only.",+   "input": {+    "names": "[component name] (default every component)",+    "accuracy": "low|medium|high|veryhigh, default low"+   },+   "output": {+    "count": "int",+    "properties": "{name: {volume_cm3, mass_kg, density, area_cm2, center_of_mass}}"+   },+   "hint": "bodies gives each part's box on the board; this gives what it weighs.",+   "pitfalls": [+    "Mass is only as good as the material on the part."+   ],+   "related": [+    "bodies",+    "component_data"+   ],+   "example": {+    "names": [+     "Enclosure"+    ]+   },+   "longRunning": false,+   "timeoutSeconds": 120,+   "proposedBy": "fusion-lane",+   "since": "0.30.14",+   "agreedBy": [+    "altium-lane",+    "kicad-lane"+   ]+  },   {    "name": "pour_state",    "tier": "native",@@ -7576,6 +7611,37 @@    "longRunning": false,    "timeoutSeconds": 120   },+  {+   "name": "cancel_run",+   "tier": "app",+   "source": "proposed",+   "summary": "Stop the bridge's own long job, between steps, keeping what is done. With nothing to stop it answers cancelRequested:false and a reason. It never claims to interrupt the tool itself.",+   "input": {+    "runId": "str (default the latest run in flight)"+   },+   "output": {+    "cancelRequested": "bool",+    "reason": "str (when false)",+    "runId": "str",+    "stage": "str at the time of the request"+   },+   "hint": "Poll the job's own status verb to see it stop.",+   "pitfalls": [+    "Which jobs can stop differs per bridge: Fusion's library imports, KiCad's autoroute, Altium's multi-step verbs between steps."+   ],+   "related": [+    "status"+   ],+   "example": {},+   "longRunning": false,+   "timeoutSeconds": 30,+   "proposedBy": "fusion-lane",+   "since": "0.30.14",+   "agreedBy": [+    "altium-lane",+    "kicad-lane"+   ]+  },   {    "name": "check_dialogs",    "tier": "app",@@ -8487,6 +8553,41 @@    "longRunning": false,    "timeoutSeconds": 30   },+  {+   "name": "preferences",+   "tier": "app",+   "source": "proposed",+   "summary": "Read the tool's own settings (all, or one by key), or change them with set. Reports per key what was applied. A tool that rewrites its settings on exit refuses set while running, with reason: \"tool_running\".",+   "input": {+    "key": "dotted path of one setting (default all)",+    "set": "{key: value} (omit to read)"+   },+   "output": {+    "current": "{key: value}",+    "applied": "{key: {ok, requested}} (with set)"+   },+   "hint": "Read first: the keys differ per tool.",+   "pitfalls": [+    "Keys differ per tool: read first.",+    "A tool that rewrites its settings on exit needs to be closed for set (reason: tool_running)."+   ],+   "related": [+    "tool_update"+   ],+   "example": {+    "set": {+     "lengthUnit": "mm"+    }+   },+   "longRunning": false,+   "timeoutSeconds": 30,+   "proposedBy": "fusion-lane",+   "since": "0.30.14",+   "agreedBy": [+    "altium-lane",+    "kicad-lane"+   ]+  },   {    "name": "prewarm",    "tier": "app",@@ -8691,6 +8792,45 @@    "timeoutSeconds": 60,    "unitsNote": "The reference bridge answers this verb in mils (xMil). A bridge following the standard answers in mm under Mm names (xMm)."   },+  {+   "name": "select_items",+   "tier": "app",+   "source": "proposed",+   "summary": "Select parts by designator on the board or the sheet, or clear the selection. A bridge that cannot select on one of them refuses it by name. verified says whether the selection was read back.",+   "input": {+    "refs": "[designator]",+    "clear": "bool",+    "where": "board (default) | sheet"+   },+   "output": {+    "selected": "[ref]",+    "failed": "[{ref, error}]",+    "verified": "bool"+   },+   "hint": "select_net selects one net; sch_zoom also frames the view; selection reads what the user selected.",+   "pitfalls": [+    "A tool that cannot report its selection answers verified:false: look at the view."+   ],+   "related": [+    "select_net",+    "sch_zoom",+    "selection"+   ],+   "example": {+    "refs": [+     "R1",+     "R2"+    ]+   },+   "longRunning": false,+   "timeoutSeconds": 30,+   "proposedBy": "fusion-lane",+   "since": "0.30.14",+   "agreedBy": [+    "altium-lane",+    "kicad-lane"+   ]+  },   {    "name": "select_net",    "tier": "app",