skill
EDA Bridge Standard: one way for an AI to drive every PCB tool
Public Made by Adomby adom
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.
← Commit history
standard 0.26.5: sch_batch (core) and log_tail (app) join (#29)
5 files changed
+133−12
README.md+4−3@@ -60,12 +60,12 @@ verb by verb: [docs/coverage.md](docs/coverage.md). <!-- coverage:start (tools/generate.py writes this) --> | Tier | Verbs | Altium | KiCad | Fusion 360 | |---|---|---|---|---|-| **core** | 94 | 94 | 94 | 91 |+| **core** | 95 | 94 | 95 | 91 | | **native** | 49 | 47 | 49 | 44 | | **checks** | 38 | 38 | 38 | 38 |-| **app** | 64 | 62 | 53 | 55 |+| **app** | 65 | 62 | 54 | 55 | | **platform** | 18 | 18 | 0 | 1 |-| standard (all but platform) | 245 | 241 | 234 | 228 |+| standard (all but platform) | 247 | 241 | 236 | 228 | <!-- 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.26.5: `sch_batch` (core) and `log_tail` (app) join the standard (#29). 247 verbs. Version 0.26.4: coverage reads KiCad bridge 1.0.91 (234 of 245: add_symbol_art, build_symbol_modes and cleanup_libs now real verbs). Version 0.26.3: coverage reads KiCad bridge 1.0.90, which answers every standard verb (swap_footprint, plate_vias, normalize_bodies, symbol_mode added; the Altium-only verbs refuse with a reason). Version 0.26.2: Fusion maps render_board and export_pos (partial), 228 of 245.
docs/coverage.md+6−4@@ -1,17 +1,17 @@ # Coverage: every standard verb on each bridge -Altium bridge 0.2.84 (the reference), KiCad bridge 1.0.91, Fusion 360 bridge 1.13.26. 60 verbs came from other bridges' proposals (tools/proposed/); they are marked *proposed*.+Altium bridge 0.2.84 (the reference), KiCad bridge 1.0.91, Fusion 360 bridge 1.13.26. 62 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** | 94 | 94 | 94 | 91 |+| **core** | 95 | 94 | 95 | 91 | | **native** | 49 | 47 | 49 | 44 | | **checks** | 38 | 38 | 38 | 38 |-| **app** | 64 | 62 | 53 | 55 |+| **app** | 65 | 62 | 54 | 55 | | **platform** | 18 | 18 | 0 | 1 |-| standard (all but platform) | 245 | 241 | 234 | 228 |+| standard (all but platform) | 247 | 241 | 236 | 228 | ## core @@ -76,6 +76,7 @@ Read and edit the design. Every bridge provides these: they are how an AI sees a | `route_net` | Route one net as tracks, segment by segment; a waypoint on another layer drops a via there. One undo step, read back. | `altium_route_net` | `kicad_route_net` | `fusion_route_net` | | `routing_state` | The WHOLE current board as data, in mm: tracks, arcs, vias, pads (with owner and net), components (ref, x, y, rotation, side), polygon pours, the outline,... | `altium_routing_state` | `kicad_routing_state` | `fusion_routing_state` | | `rules_by_kind` | The current board's ENABLED design rules grouped by rule kind (Clearance, Width, RoutingVias, ...), each group sorted by priority. Shaped from one... | `altium_rules_by_kind` | `kicad_board_rules` (partial) | `fusion_rules_by_kind` |+| `sch_batch` *proposed* | Apply a list of schematic edits to one sheet in one read and one write, all or nothing: each op is a standard schematic verb with its own arguments, seeing... | | `kicad_sch_batch` | | | `sch_bus` *proposed* | Draw a bus as a polyline (one bus segment per pair of points), optionally with a bus label such as D[0..7] or a group {SDA SCL} at its first point. One undo... | `altium_sch_bus` | `kicad_sch_bus` | `fusion_sch_bus` | | `sch_bus_entry` *proposed* | Add 45-degree bus entries: the short diagonal that joins a member wire's end to a bus. One undo step. | `altium_sch_bus_entry` | `kicad_sch_bus_entry` | `fusion_sch_bus_entry` | | `sch_connect` | Connect pins of placed parts: a wire stub from each pin's outer end plus a net label (kind label), a power port (kind power: GND-like nets get a ground... | `altium_sch_connect` | `kicad_sch_connect_to_net / kicad_sch_no_connect / kicad_sch_wire / kicad_sch_label` | `fusion_sch_connect` (partial) |@@ -253,6 +254,7 @@ Driving the application itself (launch, licence, dialogs, windows, views). Each | `license` | Drive the License Management page (UIA first - no cursor, no foreground). | `altium_license` | unsupported | `fusion_account` (partial) | | `license_status` | Plain-language answer to 'what Altium licence am I on?': the state from the window title plus a capture of the License Management page. | `altium_license_status` | `kicad_license_status` | `fusion_license_status` | | `list_commands` | Search Altium's process-launcher catalog (about 1,100 Server:Command entries parsed from the install's System/*.rcs files) by text and/or server. | `altium_list_commands` | `kicad_menu_items` (partial) | `fusion_list_commands` |+| `log_tail` *proposed* | What the tool said about itself since an offset: its own log lines and alerts (warnings and errors), so a verb that looks successful while the tool... | | `kicad_log_tail` | | | `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_board / kicad_open_schematic` (partial) | `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_board / kicad_open_schematic` (partial) | `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) | unsupported |
package.json+1−1@@ -1,6 +1,6 @@ { "slug": "eda-bridge-standard",- "version": "0.26.4",+ "version": "0.26.5", "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.",
verbs/coverage.json+24−2@@ -1,10 +1,10 @@ {- "standard": "0.26.4",+ "standard": "0.26.5", "reference": { "bridge": "altium", "version": "0.2.84" },- "proposed": 60,+ "proposed": 62, "compared": { "kicad": "1.0.91", "fusion360": "1.13.26"@@ -1006,6 +1006,17 @@ "match": "exact" } },+ {+ "name": "sch_batch",+ "tier": "core",+ "source": "proposed",+ "altium": null,+ "kicad": {+ "verb": "kicad_sch_batch",+ "match": "exact"+ },+ "fusion360": null+ }, { "name": "sch_bus", "tier": "core",@@ -3739,6 +3750,17 @@ "match": "exact" } },+ {+ "name": "log_tail",+ "tier": "app",+ "source": "proposed",+ "altium": null,+ "kicad": {+ "verb": "kicad_log_tail",+ "match": "exact"+ },+ "fusion360": null+ }, { "name": "open_document", "tier": "app",
verbs/standard.json+98−2@@ -1,10 +1,10 @@ {- "standard": "0.26.4",+ "standard": "0.26.5", "reference": { "bridge": "altium", "version": "0.2.84" },- "proposed": 60,+ "proposed": 62, "compared": { "kicad": "1.0.91", "fusion360": "1.13.26"@@ -2059,6 +2059,65 @@ "longRunning": false, "timeoutSeconds": 120 },+ {+ "name": "sch_batch",+ "tier": "core",+ "source": "proposed",+ "summary": "Apply a list of schematic edits to one sheet in one read and one write, all or nothing: each op is a standard schematic verb with its own arguments, seeing the sheet as the earlier ops left it.",+ "input": {+ "filePath": "the sheet (required)",+ "ops": "[{op: a standard schematic verb's name (sch_place_part, sch_connect_pins, sch_connect, sch_edit, sch_edit_label, sch_junction, sch_bus, sch_bus_entry, sch_text, sch_delete_wire, sch_split_wire, sch_move_region, sch_reset_fields, sch_update_from_library, annotate, ...), ...that verb's arguments}] (required)",+ "dryRun": "bool: report the plan, write nothing"+ },+ "output": {+ "results": "[{op, output, uuid?}] in order",+ "ercBefore": "the sheet's ERC counts before",+ "ercAfter": "and after",+ "failedOp": "the index of the op that failed (nothing is written then)",+ "mutated": "bool"+ },+ "hint": "A part placed in op 0 can be wired in op 1. A failing op aborts the whole batch: failedOp names it and the sheet is unchanged.",+ "pitfalls": [+ "A bridge whose tool cannot undo a partial batch answers partial: it says which ops ran before the failure."+ ],+ "related": [+ "build_schematic",+ "sch_place_part",+ "sch_connect_pins",+ "run_erc"+ ],+ "example": {+ "filePath": "C:/proj/board.kicad_sch",+ "ops": [+ {+ "op": "sch_place_part",+ "libId": "Device:R",+ "reference": "R9",+ "at": [+ 100,+ 80+ ]+ },+ {+ "op": "sch_connect_pins",+ "pairs": [+ [+ "R9.1",+ "U1.3"+ ]+ ]+ }+ ]+ },+ "longRunning": false,+ "timeoutSeconds": null,+ "proposedBy": "kicad-lane",+ "since": "0.26.4",+ "agreedBy": [+ "standard-lane",+ "fusion-lane"+ ]+ }, { "name": "sch_bus", "tier": "core",@@ -8121,6 +8180,43 @@ "longRunning": false, "timeoutSeconds": 30 },+ {+ "name": "log_tail",+ "tier": "app",+ "source": "proposed",+ "summary": "What the tool said about itself since an offset: its own log lines and alerts (warnings and errors), so a verb that looks successful while the tool complains is caught.",+ "input": {+ "sinceOffset": "int, default 0: where the last call stopped (its next)",+ "maxBytes": "int, default 200000",+ "errorsOnly": "bool: only errors and warnings"+ },+ "output": {+ "entries": "[{level, text}] newest last",+ "next": "the offset to pass as sinceOffset next time",+ "truncated": "bool"+ },+ "hint": "Carry next from call to call to see only what is new. Read it after a verb that succeeded but left the tool looking unhappy.",+ "pitfalls": [+ "A tool that writes no log of its own answers what the bridge captured from the instances it launched."+ ],+ "related": [+ "dialog_log",+ "state",+ "diagnostics"+ ],+ "example": {+ "sinceOffset": 0,+ "errorsOnly": true+ },+ "longRunning": false,+ "timeoutSeconds": null,+ "proposedBy": "kicad-lane",+ "since": "0.26.4",+ "agreedBy": [+ "standard-lane",+ "fusion-lane"+ ]+ }, { "name": "open_document", "tier": "app",