← Commit history

standard 0.3.0: 33 agreed verbs from other bridges (kicad-lane 26: exports, render_board_3d, part and graphic edits, projects, library footprints, estimate_cost, check_clearance, place_decoupling, plan_fanout; fusion-lane 7: bodies, render_board_layers, plan_route, generate_body, library_views, close_all_documents, document_info); Altium 0.2.76 reference; generate.py: a bridge's equivalents entry wins over a name match (kicad #7: kicad_edit_footprint is edit_parts, not the library edit_footprint). 236 standard verbs: Altium 187, KiCad 143, Fusion 85

Colby Knox ·98eccc92a8 ·14d ago ·parent d8816e2
7 files changed +1916−106
README.md+8−8
@@ -47,12 +47,12 @@ verb by verb: [docs/coverage.md](docs/coverage.md). <!-- coverage:start (tools/generate.py writes this) --> | Tier | Verbs | Altium | KiCad | Fusion 360 | |---|---|---|---|---|-| **core** | 79 | 63 | 57 | 28 |-| **native** | 36 | 35 | 25 | 16 |-| **checks** | 32 | 32 | 7 | 3 |-| **app** | 56 | 56 | 24 | 33 |+| **core** | 93 | 64 | 72 | 29 |+| **native** | 46 | 35 | 35 | 17 |+| **checks** | 37 | 32 | 11 | 4 |+| **app** | 60 | 56 | 25 | 35 | | **platform** | 19 | 19 | 0 | 0 |-| standard (all but platform) | 203 | 186 | 113 | 80 |+| standard (all but platform) | 236 | 187 | 143 | 85 | <!-- coverage:end -->  The **checks** tier is where the other bridges are furthest behind, and it is the cheapest to close: those verbs are@@ -133,8 +133,8 @@ Decisions so far (proposals from the KiCad and Fusion bridges, 2026-10-27; issue | | Verbs | |---|---| | **In the standard (0.2.0)** | kicad-lane batch 1: 21 schematic verbs, `sch_connect_pins` to `sch_create`, and `render_schematic` |-| **Agreed for 0.3.0, kicad-lane writes the entries** | outputs: `export_odb`, `export_ipc2581`, `export_ipc356`, `export_gencad`, `export_dxf` (board layers, one file per layer), `render_board_3d` (a 3D picture of the board from one side), `estimate_cost` (checks; the reply names its pricing source and date). Board: `remove_parts`, `edit_parts`, `align_parts`, `set_layer_count`, `remove_graphics`, `import_svg`, `copy_routing`, `cross_probe` (app), and `check_clearance`, `place_decoupling`, `plan_fanout` (checks). Projects and libraries: `project_create`, `project_info`, `project_rename`, `project_snapshot`, `read_footprint`, `edit_footprint`, `export_library_part` (native: one library part's symbol, footprint and 3D model as their own small library), `create_part_project` (native: a small real project around one library part) |-| **Agreed for 0.3.0, fusion-lane writes the entries** | `bodies` (core: the 3D bodies companion), `render_board_layers` (native: a 2D image of chosen layers or presets, svg or png, dpi, mirror), `plan_route` (checks: a path between two pads, answered as `route_net`'s arguments), `generate_body` (core: a 3D body from a package family and its dimensions), `library_views` (app), `close_all_documents` (app), `document_info` (app) |+| **In the standard (0.3.0), from kicad-lane** | outputs: `export_odb`, `export_ipc2581`, `export_ipc356`, `export_gencad`, `export_dxf` (board layers, one file per layer), `render_board_3d` (a 3D picture of the board from one side), `estimate_cost` (checks; the reply names its pricing source and date). Board: `remove_parts`, `edit_parts`, `align_parts`, `set_layer_count`, `remove_graphics`, `import_svg`, `copy_routing`, `cross_probe` (app), and `check_clearance`, `place_decoupling`, `plan_fanout` (checks). Projects and libraries: `project_create`, `project_info`, `project_rename`, `project_snapshot`, `read_footprint`, `edit_footprint`, `export_library_part` (native: one library part's symbol, footprint and 3D model as their own small library), `create_part_project` (native: a small real project around one library part) |+| **In the standard (0.3.0), from fusion-lane** | `bodies` (core: the 3D bodies companion), `render_board_layers` (native: a 2D image of chosen layers or presets, svg or png, dpi, mirror), `plan_route` (checks: a path between two pads, answered as `route_net`'s arguments), `generate_body` (core: a 3D body from a package family and its dimensions), `library_views` (app), `close_all_documents` (app), `document_info` (app) | | **Arguments, not verbs** | flipping a part is `side` on `move_parts`; `text_bounds` folds into `silk_state` | | **Merged** | `export_svg` and a board image are `render_board_layers`. There is no plain `render_board`: a 3D picture and a layer image are two jobs, and the `render_*` verbs (`render_schematic`, `render_board_3d`, `render_board_layers`) all make an image file without opening a window | | **Refused** | `batch` (every edit verb takes a list instead), `export_molecule` (an Adom feature, not an EDA job) |@@ -142,7 +142,7 @@ Decisions so far (proposals from the KiCad and Fusion bridges, 2026-10-27; issue  ## Status -Version 0.2.1: this page has one keeper (standard-lane) and bridge threads push only their own files (*Keeping it in+Version 0.3.0: 33 more verbs from other bridges, all agreed by the Altium bridge's thread: 26 from the KiCad bridge (the board exports ODB++, IPC-2581, IPC-356, GenCAD and DXF, `render_board_3d`, `remove_parts`, `edit_parts`, `align_parts`, `copy_routing`, projects, library footprints, `estimate_cost`, `check_clearance`, `place_decoupling`, `plan_fanout`) and 7 from the Fusion bridge (`bodies`, `render_board_layers`, `plan_route`, `generate_body`, `library_views`, `close_all_documents`, `document_info`). A bridge's own equivalents now win over a name match, so a verb that shares a standard name but does another job is not credited for it. Version 0.2.1: this page has one keeper (standard-lane) and bridge threads push only their own files (*Keeping it in sync*), one file per owner (`tools/equivalents/<bridge>.json`, `tools/proposed/<thread>.json`); the decisions on the KiCad and Fusion proposals are written down above; a lesson from the Fusion bridge on DRC severity is in [docs/conventions.md](docs/conventions.md). Version 0.2.0: verbs can come from any bridge. The first batch, 21 schematic verbs from the KiCad bridge (`sch_connect_pins`, `sch_bus`, `sch_items`, `sch_pins`, `sch_trace_point`, `render_schematic` ...), was agreed by the
docs/coverage.md+72−39
@@ -1,17 +1,17 @@ # Coverage: every standard verb on each bridge -Altium bridge 0.2.75 (the reference), KiCad bridge 1.0.62, Fusion 360 bridge 1.12.1. 21 verbs came from other bridges' proposals (tools/proposed/); they are marked *proposed*.+Altium bridge 0.2.76 (the reference), KiCad bridge 1.0.62, Fusion 360 bridge 1.12.1. 54 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; blank is missing. Generated by `tools/generate.py` from `verbs/coverage.json`; do not edit by hand.  | Tier | Verbs | Altium | KiCad | Fusion 360 | |---|---|---|---|---|-| **core** | 79 | 63 | 57 | 28 |-| **native** | 36 | 35 | 25 | 16 |-| **checks** | 32 | 32 | 7 | 3 |-| **app** | 56 | 56 | 24 | 33 |+| **core** | 93 | 64 | 72 | 29 |+| **native** | 46 | 35 | 35 | 17 |+| **checks** | 37 | 32 | 11 | 4 |+| **app** | 60 | 56 | 25 | 35 | | **platform** | 19 | 19 | 0 | 0 |-| standard (all but platform) | 203 | 186 | 113 | 80 |+| standard (all but platform) | 236 | 187 | 143 | 85 |  ## core @@ -20,47 +20,60 @@ Read and edit the design. Every bridge provides these: they are how an AI sees a | Verb | What it does | Altium | KiCad | Fusion 360 | |---|---|---|---|---| | `add_body` | Put a 3D body on a footprint of a PcbLib: a STEP model, or an extruded box when no step is given. It REPLACES the footprint's existing 3D bodies (a... | `altium_add_body` |  | `fusion_attach_3d_package` (partial) |-| `add_models` | Attach one or more PCBLIB footprint models, parameters, comment and description to a SchLib component (Altium's several-footprints-per-symbol mechanism). | `altium_add_models` |  |  |+| `add_models` | Attach one or more PCBLIB footprint models, parameters, comment and description to a SchLib component (Altium's several-footprints-per-symbol mechanism). | `altium_add_models` | `kicad_footprint_models` (partial) |  | | `add_symbol_art` | Draw the chip-outline artwork (the chip-thumbnailer polylines adom-symbol baked into the KiCad symbol) into a SchLib component, fitted to its body... | `altium_add_symbol_art` |  |  |+| `align_parts` *proposed* | Line parts up on a common left, right, top, bottom or centre line, or space them evenly, by courtyard box or by anchor point. One undo step, with... |  | `kicad_align_footprints` |  | | `apply_silkscreen` | Land a silkscreen plan in one undo step: designators and comments moved, sized and turned (or hidden), free overlay texts and lines added (bottom texts... | `altium_apply_silkscreen` | `kicad_silk_fields_batch / kicad_silk_text_batch / kicad_silk_graphics_batch` | `fusion_apply_silkscreen` | | `board_outline` | Draw the board shape as tracks and arcs on a mechanical layer: the outline a fab house reads from the Gerbers. A board built by script has its shape but... | `altium_board_outline` | `kicad_board_outline` | `fusion_board_outline` | | `board_shape` | Redefine the CURRENT board's outline as a wMm x hMm rectangle at (x0Mm, y0Mm) by rewriting the board outline's segments. | `altium_board_shape` | `kicad_board_outline` | `fusion_board_shape` |-| `board_summary` | One-screen summary of the current board, shaped from one read_board round trip: component counts by side, nets, copper layers actually in use, rule counts. | `altium_board_summary` | `kicad_board_summary` | `fusion_board_summary` |+| `board_summary` | One-screen summary of the current board, shaped from one read_board round trip: component counts by side, nets, copper layers actually in use, rule counts. | `altium_board_summary` | `kicad_board_summary` | `fusion_board_info` (partial) |+| `bodies` *proposed* | Every part's 3D body as a box: its footprint rectangle on the board and its height range above the surface it sits on (a bottom part measures down from the... | `altium_bodies` | `kicad_bodies` | `fusion_bodies` | | `clone_symbol` | Copy a symbol inside the current SchLib under a new name, all display modes included. | `altium_clone_symbol` |  |  | | `component_data` | Placement data for one board component, or for all of them: footprint pattern, comment, layer/side, position, rotation, size, pad count and the nets on its... | `altium_component_data` | `kicad_component_data` | `fusion_component_data` | | `component_pins` | Every pad of one board component with its net, position, layer, size and hole. | `altium_component_pins` | `kicad_component_pins` | `fusion_component_pins` | | `copper_layers` | Every copper layer Altium can address on the current board (top, mid 1-30, planes 1-16, bottom) with names and visibility. | `altium_copper_layers` | `kicad_copper_layers` | `fusion_copper_layers` | | `copy_footprint` | Duplicate a footprint inside the current PcbLib under a new name (every primitive replicated). | `altium_copy_footprint` |  |  |-| `create_footprint` | Create one footprint from a pad list in a PcbLib (the library is created and saved if the path does not exist) and return a proof frame. | `altium_create_footprint` | `kicad_create_footprint` |  |-| `create_symbol` | Create one rectangular symbol from a pin list in a SchLib (the library is created and saved if the path does not exist) and return a proof frame. | `altium_create_symbol` | `kicad_create_symbol` |  |+| `copy_routing` *proposed* | Copy the tracks and vias inside a box to an offset, remapping nets by pairing parts (a designator map or pattern), so a repeated channel gets the same... |  | `kicad_copy_routing` |  |+| `create_footprint` | Create one footprint from a pad list in a PcbLib (the library is created and saved if the path does not exist) and return a proof frame. | `altium_create_footprint` | `kicad_fp_create` |  |+| `create_symbol` | Create one rectangular symbol from a pin list in a SchLib (the library is created and saved if the path does not exist) and return a proof frame. | `altium_create_symbol` | `kicad_sym_create` |  | | `doc_params` | Read or set a sheet's document parameters: the title block (Title, DocumentNumber, Revision, DrawnBy, Author, CompanyName, ...). | `altium_doc_params` |  |  |+| `edit_footprint` *proposed* | Edit a library footprint in place: change, delete, add or renumber pads; add, replace or delete graphics on a layer; set its description, tags and... |  | `kicad_fp_edit` |  |+| `edit_parts` *proposed* | Edit placed parts: value, designator, any field (add, change, remove), do-not-populate, exclusion from the BOM or position files, mounting type and the... |  | `kicad_edit_footprint` |  | | `find_symbol` | Find symbols (or footprints with kind:'footprint') by part of their name across libraries: the given ones, or every installed .SchLib/.PcbLib. | `altium_find_symbol` | `kicad_find_symbol` |  |-| `footprint_primitives` | Geometry dump of one PLACED component: its tracks, arcs, pads (with solder and paste mask expansion in um) and texts in mils with layer ids; other primitive... | `altium_footprint_primitives` | `kicad_fp_info` (partial) |  |-| `layer_stack` | The CURRENT board's stack-up: copper layers in order with copper thickness and the dielectric under each (height, constant, material), and the total... | `altium_layer_stack` | `kicad_layer_stack` | `fusion_layer_stack` |+| `footprint_primitives` | Geometry dump of one PLACED component: its tracks, arcs, pads (with solder and paste mask expansion in um) and texts in mils with layer ids; other primitive... | `altium_footprint_primitives` | `kicad_footprint_graphics` (partial) |  |+| `generate_body` *proposed* | Make a part's 3D body from its package family and its datasheet dimensions (chip, SOIC, QFN, QFP, BGA, SOT-23, DFN, MELF, electrolytic can, crystal, pin... |  |  |  |+| `import_svg` *proposed* | Import SVG artwork (a logo, a label) as filled polygons on a silkscreen, copper, mask or user layer, at a position and size; curves flattened, holes kept.... |  | `kicad_import_svg` |  |+| `layer_stack` | The CURRENT board's stack-up: copper layers in order with copper thickness and the dielectric under each (height, constant, material), and the total... | `altium_layer_stack` | `kicad_layer_stack` | `fusion_board_stackup` | | `layers` | The current board's layer set with ids, names, kind and whether each is displayed. | `altium_layers` |  | `fusion_layers` | | `layers_in_use` | Which layers of the current board actually carry primitives: copper layers with copper (densest first) and every layer with anything on it. | `altium_layers_in_use` | `kicad_layers_in_use` | `fusion_layers_in_use` | | `list_designators` | Every component designator on the current board. | `altium_list_designators` | `kicad_list_designators` | `fusion_list_designators` | | `list_library` | Names of every component in a .SchLib or every footprint in a .PcbLib (kind taken from the extension). Opens the library; no screenshot. | `altium_list_library` | `kicad_list_footprints / kicad_list_symbols` (partial) | `fusion_library_parts` (partial) | | `list_nets` | Every net on the current board with its pad count. | `altium_list_nets` | `kicad_list_nets` | `fusion_list_nets` |-| `move_parts` | Move and rotate placed components; each part is read back to 0.001 mm and the exact rotation. One undo step. | `altium_move_parts` | `kicad_move_footprint` | `fusion_move_parts` |+| `move_parts` | Move, rotate and flip placed components (side top or bottom; flip:true turns a part over); each part is read back to 0.001 mm, the exact rotation and its... | `altium_move_parts` | `kicad_move_footprint / kicad_flip_footprint` | `fusion_move_parts` | | `net_connections` | Every pad on the board with its net and owner (Designator.Pad), plus a bounding span and the airline length (minimum spanning tree over its pads, airlineMm)... | `altium_net_connections` | `kicad_trace_net / kicad_find_connections` (partial) | `fusion_net_connections` | | `normalize_bodies` | Move every 3D body of a PcbLib's footprints (or one footprint) onto its pad cluster. A body added through the canvas lands 50000 mil from the pads in the... | `altium_normalize_bodies` |  |  | | `part_parameters` | The parameter names a project's parts carry (with how many parts carry each), or with name, that parameter's value on every part. | `altium_part_parameters` |  |  |-| `place_on_pcb` | Place ONE footprint from a PcbLib on a new board and return a proof frame. The single-part predecessor of altium_test_board. | `altium_place_on_pcb` | `kicad_place_footprint` |  |+| `place_on_pcb` | Place ONE footprint from a PcbLib on a new board and return a proof frame. The single-part predecessor of altium_test_board. | `altium_place_on_pcb` | `kicad_place_footprint / kicad_add_footprint` |  | | `place_on_sch` | Place one symbol, or a ';' list of symbols, from the open SchLib on ONE new sheet (sheet sized FROM the measured parts: 500 mil gaps, 600 mil margins, A4... | `altium_place_on_sch` |  |  | | `place_vias` | Place vias (through, top to bottom). One undo step, read back. | `altium_place_vias` | `kicad_add_via` | `fusion_place_vias` | | `plate_vias` | Make every drilled pad in a PcbLib a plated MULTI-LAYER pad (all footprints, or footprintName). adom-lbr writes heatsink vias as pads with a hole; Altium... | `altium_plate_vias` |  |  |+| `project_create` *proposed* | Create a new project folder with a project file, an empty schematic and an empty board (2 to 32 copper layers), with a title and text variables. |  | `kicad_project_create` |  |+| `project_info` *proposed* | A project at a glance: name, files with sizes and dates, the sheet tree, the board (layers, parts, nets, size), text variables, net classes, last change,... |  | `kicad_project_info` |  |+| `project_rename` *proposed* | Rename a project: the project file, the root sheet, the board and the tool's side files, with the references inside them updated. Refused while the tool has... |  | `kicad_project_rename` |  | | `read_board` | ONE round trip: components, nets, layers, copper, rules, occupancy, outline. | `altium_read_board` | `kicad_board_summary` (partial) | `fusion_board_info / fusion_get_design_info` (partial) |+| `read_footprint` *proposed* | Every detail of one library footprint: pads (number, type, shape, position, size, drill, layers), the layers it uses, its courtyard box, graphics per layer,... |  | `kicad_fp_info` |  | | `read_rules` | Every design rule on the current board, flat, disabled ones included: name, kind ordinal, enabled, priority, both scope expressions, comment, and Altium's... | `altium_read_rules` | `kicad_list_design_rules` | `fusion_read_rules` | | `read_schematic` | Components on the CURRENT schematic sheet (designator, library reference, comment, position, parameters) in one agent round trip. | `altium_read_schematic` | `kicad_sch_components` (partial) | `fusion_schematic` (partial) |-| `read_symbol` | Read a SchLib component back: description, display-mode count, the pins of mode 0 (designator, name, electrical type), every parameter with its hidden flag,... | `altium_read_symbol` | `kicad_read_symbol` |  |+| `read_symbol` | Read a SchLib component back: description, display-mode count, the pins of mode 0 (designator, name, electrical type), every parameter with its hidden flag,... | `altium_read_symbol` | `kicad_sym_info` |  | | `remove_footprint` | Delete one footprint from the current PcbLib. | `altium_remove_footprint` |  |  |+| `remove_graphics` *proposed* | Remove board graphics (lines, rectangles, circles, arcs, polygons, texts, dimensions) by id, or every one on a layer and of a kind. One undo step. |  | `kicad_delete_graphics` |  | | `remove_items` | Delete specific free tracks and vias, given exactly as altium_routing_state returned them. One undo step. | `altium_remove_items` | `kicad_remove_route` (partial) | `fusion_remove_items` |-| `remove_symbol` | Delete one component from the current SchLib. | `altium_remove_symbol` | `kicad_remove_symbol` |  |+| `remove_parts` *proposed* | Remove placed parts from the board by designator, as one undo step. The library is not touched (that is remove_footprint). |  | `kicad_delete_footprint` |  |+| `remove_symbol` | Delete one component from the current SchLib. | `altium_remove_symbol` | `kicad_sym_delete` |  | | `rename_footprint` | Rename a footprint in the current PcbLib. | `altium_rename_footprint` |  |  | | `rename_symbol` | Rename a component (LibReference) in the current SchLib. | `altium_rename_symbol` |  |  | | `ripup_nets` | Delete every free track, arc and via on each named net. One undo step. | `altium_ripup_nets` |  | `fusion_ripup_nets` |-| `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` |+| `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 / kicad_add_track` | `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_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... |  | `kicad_sch_bus` |  |@@ -82,13 +95,14 @@ Read and edit the design. Every bridge provides these: they are how an AI sees a | `sch_place_part` | Place a component from a .SchLib onto an EXISTING sheet at a position, with its library parameters (MPN, Manufacturer, distributor numbers) and its... | `altium_sch_place_part` | `kicad_sch_place_symbol` |  | | `sch_reset_fields` *proposed* | Put parts' designator and value text (or the named fields) back where the library symbol places them, through each part's rotation and mirror. One undo step. |  | `kicad_sch_reset_fields` |  | | `sch_sheet_pins` *proposed* | A sheet symbol's pins: list, add, edit (rename, kind, move along an edge) or delete. import:true adds a pin for every hierarchical port inside the child... | `altium_sch_sheet_symbol` (partial) | `kicad_sch_sheet_pins` |  |-| `sch_sheet_symbol` | Make a design hierarchical: a sheet symbol on the parent sheet for a child sheet, its entries joined to the parent's nets, and matching ports on the child.... | `altium_sch_sheet_symbol` | `kicad_sch_sheet_symbol` |  |+| `sch_sheet_symbol` | Make a design hierarchical: a sheet symbol on the parent sheet for a child sheet, its entries joined to the parent's nets, and matching ports on the child.... | `altium_sch_sheet_symbol` | `kicad_sch_sheet` (partial) |  | | `sch_split_wire` *proposed* | Split the wire through a point into two wires there, with a junction dot at the cut, so a new branch can end on a wire end. One undo step. |  | `kicad_sch_split_wire` |  | | `sch_swap_part` | Replace a placed part with another library part (a different value, package or symbol) at the same place, designator and rotation, keeping its connections:... | `altium_sch_swap_part` | `kicad_sch_replace_symbol` (partial) |  | | `sch_text` *proposed* | Add free text to a sheet (a note, a title, a design comment) with size, angle, justification, bold and italic. Text has no electrical meaning. One undo step. |  | `kicad_sch_text` |  | | `sch_trace_point` *proposed* | Everything electrically connected at a point on a sheet: the wires, labels, pins, junctions, sheet pins and no-connect markers there, and for each net they... |  | `kicad_sch_trace_point` |  | | `schematic_data` | Components on a schematic sheet (filePath, else the CURRENT sheet) with their pins (number, name, electrical type), position and orientation. designator... | `altium_schematic_data` | `kicad_sch_components` (partial) |  |-| `set_models` | Replace every footprint model on a SchLib component with ONE PCBLIB model (set_params footprint and add_models APPEND, which is how a symbol ends up with two). | `altium_set_models` |  |  |+| `set_layer_count` *proposed* | Set the board's copper layer count (2, 4, 6 or 8): the layer table and the stack-up, keeping the board thickness. |  | `kicad_set_layer_count` |  |+| `set_models` | Replace every footprint model on a SchLib component with ONE PCBLIB model (set_params footprint and add_models APPEND, which is how a symbol ends up with two). | `altium_set_models` | `kicad_footprint_models` (partial) |  | | `set_outline` | Reshape the current board's outline (a rectangle with rounded corners, or a polygon). One undo step. | `altium_set_outline` | `kicad_board_outline` | `fusion_set_outline` | | `set_params` | Set parameters on a SchLib component, optionally its comment, and optionally link a footprint by name. | `altium_set_params` |  |  | | `set_track_width` | Set the width of the EXISTING tracks and arcs on nets or a net class (rules only steer new routing). Widen power nets after routing, or thin a net that... | `altium_set_track_width` | `kicad_modify_track` (partial) | `fusion_set_track_width` |@@ -105,32 +119,42 @@ Wraps the EDA tool's own feature (its DRC, ERC, Gerbers, pours, Update PCB). Eve  | Verb | What it does | Altium | KiCad | Fusion 360 | |---|---|---|---|---|-| `add_rule` | Add one SCOPED design rule that set_design_rules' board-wide values cannot express: a net's or class's clearance or width, a length limit, a matched-length... | `altium_add_rule` | `kicad_add_rule` |  |-| `annotate` | Number every '?' designator (R?, C?, U?) across the project's sheets: the lowest free number per prefix, top-left first on each sheet. dryRun shows the plan. | `altium_annotate` | `kicad_annotate` |  |-| `apply_pours` | Add solid polygon pours from outlines and pour them, each with its own connect style (solid joints or thermal spokes), plus pour keepouts (polygon cutouts);... | `altium_apply_pours` | `kicad_add_zone / kicad_apply_zone_plan` | `fusion_apply_pours` |+| `add_rule` | Add one SCOPED design rule that set_design_rules' board-wide values cannot express: a net's or class's clearance or width, a length limit, a matched-length... | `altium_add_rule` | `kicad_custom_rules` |  |+| `annotate` | Number every '?' designator (R?, C?, U?) across the project's sheets: the lowest free number per prefix, top-left first on each sheet. dryRun shows the plan. | `altium_annotate` | `kicad_sch_annotate` |  |+| `apply_pours` | Add solid polygon pours from outlines and pour them, each with its own connect style (solid joints or thermal spokes), plus pour keepouts (polygon cutouts);... | `altium_apply_pours` | `kicad_add_zone / kicad_apply_zone_plan` | `fusion_change_pours` (partial) | | `autoroute` | Altium's own autorouter (Situs) on the current board: picks a strategy, keeps existing routing locked by default, routes, and answers the unconnected count... | `altium_autoroute` | `kicad_autoroute` | `fusion_autoroute` | | `build_symbol_modes` | Build ONE SchLib component with N display modes (Normal + Alternate 1..N-1) from a symbol_modes spec file on this machine, and return a proof frame. | `altium_build_symbol_modes` |  |  | | `cleanup_libs` | Remove the factory-default stray every fresh library carries: Component_1 from the current SchLib and an empty (no pads) PCBComponent_1 from the current PcbLib. | `altium_cleanup_libs` |  |  | | `compile` | Compile a project and return Altium's Messages panel (ERC + connectivity) with counts by class. With no path it compiles Altium's bundled example project. | `altium_compile` |  |  | | `component_classes` | List, make or remove component classes on the board, each optionally with a room: a placement area that keeps its parts together (fitted around the parts or... | `altium_component_classes` |  |  |+| `create_part_project` *proposed* | Generate a small real project (schematic and board) around one library part, so the part can be shown and tested in every view: schematic, 2D board and 3D... |  | `kicad_make_part_project` (partial) |  | | `diff_pairs` | Differential pairs on the current board: list them, define one from two nets (replacing a pair of that name), or remove one. Altium's differential-pair... | `altium_diff_pairs` |  |  |-| `export_bom` | Bill of materials export: altium_run_outjob with the assembly OutJob and the 'Folder Structure' medium as defaults. | `altium_export_bom` | `kicad_export_bom_csv` (partial) | `fusion_export_bom` |-| `export_gerber` | Gerber/drill export: altium_run_outjob with the fabrication OutJob and the 'Folder Structure' medium as defaults. | `altium_export_gerber` | `kicad_export_gerber` | `fusion_export_gerber` |-| `export_manufacturing` | A project's manufacturing set in one call: Gerbers, NC drill, pick and place (CSV, mm) and the BOM, from an OutJob the bridge writes beside the project... | `altium_export_manufacturing` | `kicad_export_manufacturing` | `fusion_export_gerbers / fusion_export_cpl / fusion_export_bom` (partial) |+| `export_bom` | Bill of materials export: altium_run_outjob with the assembly OutJob and the 'Folder Structure' medium as defaults. | `altium_export_bom` | `kicad_export_bom_csv` (partial) | `fusion_export_bom / fusion_board_bom` |+| `export_dxf` *proposed* | Export chosen board layers to DXF, one file per layer (the outline, panel drawings, stencils, enclosure work). |  | `kicad_export_dxf` | `fusion_export_dxf` |+| `export_gencad` *proposed* | Export the board as GenCAD 1.4, the input of test-fixture tools and some assembly houses' CAM. |  | `kicad_export_gencad` |  |+| `export_gerber` | Gerber/drill export: altium_run_outjob with the fabrication OutJob and the 'Folder Structure' medium as defaults. | `altium_export_gerber` | `kicad_export_gerber` | `fusion_export_gerbers` |+| `export_ipc2581` *proposed* | Export the board as IPC-2581: one XML file with copper, drill, stack-up, netlist and BOM, through the tool's own exporter. |  | `kicad_export_ipc2581` |  |+| `export_ipc356` *proposed* | Export the IPC-D-356 netlist of the board, for bare-board electrical test (flying probe or bed of nails). |  | `kicad_export_ipc356` |  |+| `export_library_part` *proposed* | Export one library part into its own small library files: a symbol library with only its symbol, a footprint library with only its footprint, and its 3D... |  | `kicad_export_part` (partial) |  |+| `export_manufacturing` | A project's manufacturing set in one call: Gerbers, NC drill, pick and place (CSV, mm) and the BOM, from an OutJob the bridge writes beside the project... | `altium_export_manufacturing` | `kicad_export_gerber / kicad_export_pos` (partial) | `fusion_export_gerbers / fusion_export_cpl / fusion_export_bom` (partial) |+| `export_odb` *proposed* | Export the board as ODB++ (copper, drill, stack-up, netlist and parts in one archive) through the tool's own exporter. |  | `kicad_export_odb` |  | | `export_pdf` | Every sheet of a project as one PDF, plus on request the board's composite print, Altium's assembly drawings (top and bottom, designators on the parts) and... | `altium_export_pdf` | `kicad_export_pdf` |  | | `export_step` | Headless STEP export of a board. Default lane 'outjob': Altium's own ExportSTEP output run from a throwaway project in %TEMP% that points at the board - no... | `altium_export_step` | `kicad_export_step` | `fusion_export_step` | | `install_library` | Register a library file in Altium's Installed Libraries (IntegratedLibraryManager.InstallLibrary) so its parts appear in the Components panel. | `altium_install_library` | `kicad_install_library` |  | | `install_library_bundle` | One-click install of a wiki library bundle (zip of .SchLib/.PcbLib): unpack, register, open the library, prove it with a frame. | `altium_install_library_bundle` | `kicad_install_library_bundle` | `fusion_install_library_bundle` | | `list_installed_libraries` | Every library in Altium's Installed Libraries list (read-only). | `altium_list_installed_libraries` |  |  |-| `net_classes` | Net classes on the current board: list them with their nets, or make one (replacing a class of that name) with an optional width and clearance rule scoped... | `altium_net_classes` | `kicad_net_classes` | `fusion_net_classes` |-| `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` |+| `net_classes` | Net classes on the current board: list them with their nets, or make one (replacing a class of that name) with an optional width and clearance rule scoped... | `altium_net_classes` | `kicad_netclasses` | `fusion_net_classes` |+| `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_extract_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` |  |  | | `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) |  |-| `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` |+| `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_zone_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. |  | `kicad_project_snapshot` |  | | `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` |+| `render_board_3d` *proposed* | Render a 3D picture of the board from one side to an image file, through the tool's own renderer, without opening a window. |  | `kicad_render_board` |  |+| `render_board_layers` *proposed* | Render chosen board layers to an image file without opening a window: a preset view (copper, silkscreen, solder mask, paste, outline, drill, assembly or... |  | `kicad_export_svg` (partial) |  | | `render_schematic` *proposed* | Render a sheet to an image without opening a window, through the tool's own plotter, and keep visual baselines: baseline set stores the image, baseline... | `altium_show_schematic` (partial) | `kicad_render_schematic` |  | | `replicate_layout` | Copy one channel's placement to matching channels: each target keeps its anchor part where it is and every other part takes the source's offset and rotation... | `altium_replicate_layout` |  |  |-| `repour` | Repour every polygon on the board (Altium's Repour All) and answer the copper after. Runs outside the script engine so scoped rules apply. | `altium_repour` | `kicad_repour` | `fusion_repour` |+| `repour` | Repour every polygon on the board (Altium's Repour All) and answer the copper after. Runs outside the script engine so scoped rules apply. | `altium_repour` | `kicad_refill_zones` | `fusion_repour` | | `routing_drc` | Design-rule violations on the current board WITH locations, plus the unrouted (ratsnest) count, as one clean/not-clean answer. | `altium_routing_drc` | `kicad_routing_validate` (partial) | `fusion_routing_drc` | | `run_drc` | Run the design rule check on a board and read the violation markers back. PCB:DesignRuleCheck opens a MODAL; the bridge clicks 'Run Design Rule Check'... | `altium_run_drc` | `kicad_run_drc` | `fusion_run_drc` | | `run_erc` | Electrical rules check. Same handler as altium_compile: in Altium, compiling the project IS the ERC. | `altium_run_erc` | `kicad_run_erc` | `fusion_run_erc` |@@ -140,7 +164,7 @@ Wraps the EDA tool's own feature (its DRC, ERC, Gerbers, pours, Update PCB). Eve | `symbol_mode` | Show one display mode (0 = Normal, 1.. = alternates) of the CURRENT SchLib component in the editor and capture a frame. Drives the editor's own mode toggle,... | `altium_symbol_mode` |  |  | | `teardrops` | Add (or remove) teardrops with Altium's own Tools > Teardrops: on vias and through-hole pads, SMD pads, track width changes and T-junctions, for the whole... | `altium_teardrops` |  |  | | `uninstall_library` | Remove libraries from Altium's Installed Libraries: the inverse of install_library / install_library_bundle. Library files are never touched. | `altium_uninstall_library` | `kicad_uninstall_library` |  |-| `update_pcb` | Design > Update PCB Document from the schematic (the engineering change order): parts added, removed or renamed, nets and footprints updated on the board.... | `altium_update_pcb` | `kicad_update_pcb` |  |+| `update_pcb` | Design > Update PCB Document from the schematic (the engineering change order): parts added, removed or renamed, nets and footprints updated on the board.... | `altium_update_pcb` | `kicad_update_pcb_from_schematic` (partial) |  |  ## checks @@ -156,11 +180,13 @@ Engineering computed from the board model, not by the tool: one shared engine, s | `build_board` | Build a NEW board from a parts list and a netlist: outline (rounded corners allowed), every footprint from one PcbLib placed by its own origin, pad nets... | `altium_build_board` |  |  | | `build_footprint` | Build a complete footprint (pads, silkscreen, courtyard, arcs) in a PcbLib from a kicad2altium spec file on this machine, and return a proof frame. | `altium_build_footprint` |  |  | | `build_schematic` | Draw a design's schematic from its netlist with the project library's symbols, inside a new project (.PrjPcb with the board and libraries), compile it, and... | `altium_build_schematic` |  | `fusion_schematic_plan / fusion_schematic_run` (partial) |+| `check_clearance` *proposed* | Measure the gaps between parts, courtyard to courtyard or pad copper to pad copper, for the listed parts or the whole board, and report every pair under a... |  | `kicad_check_clearance` |  | | `check_orientation` | Advisory: 2-pad parts whose rotation could be better. Each orthogonal rotation is scored in place by airline length (a routable net's MST with the pad... | `altium_check_orientation` |  |  | | `copper_balance` | How much of each copper layer is copper (tracks, pads, vias and what Altium actually poured, inside the outline; a plane counts full), and how far apart... | `altium_copper_balance` |  |  | | `cross_check` | Compare one schematic sheet's designators with a board's. Altium holds ONE current document, so the verb activates the board, reads it, then activates the... | `altium_cross_check` | `kicad_analyze_connections` (partial) |  | | `current_capacity` | Will this trace carry the current? For each power net and its current: the narrowest track on every layer it is routed on against the width IPC-2221 needs... | `altium_current_capacity` |  |  |-| `fab_check` | Before ordering: the board's fab-relevant minimums measured from the live board (narrowest track, smallest via drill, diameter and annular ring, smallest... | `altium_fab_check` | `kicad_fab_check` |  |+| `estimate_cost` *proposed* | The board's numbers a fab quote needs (size, layers, thickness, smallest track, gap and drill, holes, SMD and through-hole parts and joints, unique parts)... |  | `kicad_estimate_cost` |  |+| `fab_check` | Before ordering: the board's fab-relevant minimums measured from the live board (narrowest track, smallest via drill, diameter and annular ring, smallest... | `altium_fab_check` | `kicad_validate_for_fab` |  | | `find_space` | Free spots on the board for a part near another (clear of every other part on that side, of that side's tracks and vias, and inside the outline), nearest... | `altium_find_space` |  |  | | `footprint_from_land_pattern` | Build a complete footprint from the land pattern a datasheet prints: pads numbered the standard way (chip, dual SOIC/TSSOP/DFN, SOT, quad QFP/QFN, BGA), an... | `altium_footprint_from_land_pattern` |  |  | | `height_check` | Will it fit the enclosure? Each part's height from its 3D bodies (top and bottom side), the parts over a height limit board-wide or under a lid feature in a... | `altium_height_check` |  |  |@@ -170,11 +196,14 @@ Engineering computed from the board model, not by the tool: one shared engine, s | `length_tune` | Lengthen a routed net to a target length, or to match another net (a pair's skew, a DDR byte lane): a serpentine in its longest straight track that has room... | `altium_length_tune` |  |  | | `net_lengths` | Routed length of every net (or the ones named) on the live board, by layer with its vias; the skew inside each differential pair; and the spread of... | `altium_net_lengths` |  |  | | `pin_pad_check` | Do the footprints fit their symbols? Part by part, the symbol's pin numbers (from the sheet files) against the footprint's pad names (from the board): pins... | `altium_pin_pad_check` |  |  |-| `placement_check` | Review the placement before routing: parts whose courtyards (pads and body, grown by a margin) overlap on the same side, parts off the board or over its... | `altium_placement_check` | `kicad_placement_validate` (partial) |  |+| `place_decoupling` *proposed* | Plan positions for decoupling capacitors beside an IC's power pins (each cap just outside the courtyard, its power pad facing the pin), answered as... |  | `kicad_place_decoupling` |  |+| `placement_check` | Review the placement before routing: parts whose courtyards (pads and body, grown by a margin) overlap on the same side, parts off the board or over its... | `altium_placement_check` | `kicad_placement_validate / kicad_score_placement` (partial) |  |+| `plan_fanout` *proposed* | Plan the fanout of a BGA or QFN/QFP: the pad pitch, dogbone or via-in-pad per pad, the escape layer, surface stubs for the outer ring and a via grid for an... |  | `kicad_plan_fanout` |  |+| `plan_route` *proposed* | Plan a path for one net between two pads without changing the board: a grid search around the existing copper that keeps the clearance rules, on the allowed... |  |  | `fusion_plan_route` | | `read_sheet_file` | Read a schematic sheet straight from its .SchDoc file, without Altium (it need not be installed or running): every part with its designator, library... | `altium_read_sheet_file` |  | `fusion_read_sheet_file` | | `return_path` | Where signal tracks lose their reference: for every signal net, the length of track on each layer that runs over no pour or plane copper on either... | `altium_return_path` |  |  | | `review_board` | Design-review checks (14) over one board read; schematic checks with includeSchematic. | `altium_review_board` | `kicad_lint_board` (partial) |  |-| `route_pair` | Route a differential pair as a pair: one centreline from the source pads' midpoint through waypoints to the destination pads' midpoint, each net offset to... | `altium_route_pair` | `kicad_route_pair` |  |+| `route_pair` | Route a differential pair as a pair: one centreline from the source pads' midpoint through waypoints to the destination pads' midpoint, each net offset to... | `altium_route_pair` | `kicad_route_diff_pair` |  | | `schematic_review` | Review the schematic before Update PCB: every placed pin (read from the sheet files, with its electrical type) against Altium's compiled netlist. Errors:... | `altium_schematic_review` | `kicad_sch_check / kicad_design_review / kicad_lint_schematic` (partial) |  | | `silk_designators` | Place every reference designator the way assembly houses want: one size, upright, beside its own part, clear of every pad (JLCPCB: 0.15 mm), every other... | `altium_silk_designators` |  |  | | `test_board` | Place one footprint, or a ';' list, from the open PcbLib on ONE board: a NEW board (wMm x hMm outline) when pcbPath is new or omitted, APPENDED to the... | `altium_test_board` |  |  |@@ -195,22 +224,26 @@ Driving the application itself (launch, licence, dialogs, windows, views). Each | `animate_view` | Camera/zoom choreography on the current document - native Altium camera commands, animated by Altium itself. | `altium_animate_view` |  |  | | `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` |  | `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... |  |  | `fusion_close_all_documents` | | `close_document` | Close ONE open document by path through its document handle. Never saves. | `altium_close_document` |  | `fusion_close_document` | | `connect_workspace` | Open Altium's workspace picker (the 'Not Connected' menu) and return a screenshot with a coordMap. The list is a custom control with no UIA children, so the... | `altium_connect_workspace` |  |  |+| `cross_probe` *proposed* | From a schematic part to the board part linked to it, and back, by designator, the schematic symbol's id or its sheet path; optionally select them in the tool. |  | `kicad_cross_probe` |  | | `demo` | The tour. Default: one background beat per call with a screenshot. live:true = the narrated FOREGROUND show: ab caption + document + in-bridge camera... | `altium_demo` | `kicad_demo` | `fusion_demo` | | `describe` | This list - the bridge's verbs and schemas for ab's Verbs tab. | `altium_describe` | `kicad_describe` | `fusion_describe` | | `diagnostics` | Bridge-side facts for a bug report: environment variables, every Altium install found, Altium's windows, the agent status block and the cache directory. | `altium_diagnostics` | `kicad_diagnostics` |  | | `dialog_log` | What the standing dialog reaper (and the bridge's own recoveries) pressed, newest last: nuisance boxes, script-error boxes, discarded save prompts, silent... | `altium_dialog_log` |  | `fusion_dialog_log` |-| `dismiss_dialogs` | Press one named button (default OK) on the detected Altium dialogs through UIA - no cursor, no focus steal. titles narrows it to dialogs whose title... | `altium_dismiss_dialogs` | `kicad_dismiss_dialogs` | `fusion_dismiss_dialogs` |+| `dismiss_dialogs` | Press one named button (default OK) on the detected Altium dialogs through UIA - no cursor, no focus steal. titles narrows it to dialogs whose title... | `altium_dismiss_dialogs` | `kicad_dismiss_dialogs` | `fusion_dismiss_blocking_dialogs` |+| `document_info` *proposed* | The active document: its name, what kind it is, whether it has unsaved changes, where it is saved and which version it is. Read only; opens nothing. |  |  | `fusion_document_info` | | `ensure_licensed` | One call to get a usable Altium: launch if needed, then claim a seat (Use License via UIA). Optional escalations: sign out to force a seat release, or start... | `altium_ensure_licensed` |  |  | | `eval` | Run a DelphiScript snippet inside Altium (optional Var block, then Begin ... End;) on the CURRENT document, or on filePath opened first. | `altium_eval` |  |  | | `extension_ping` | Does the AdomBridge .NET extension answer? Sends AdomBridge:Ping through the -R lane and waits up to 30 s for its result file. | `altium_extension_ping` |  |  | | `foreground` | Bring Altium in front of the user - the sanctioned exception to the never-foreground rule. | `altium_foreground` |  |  |-| `install` | Install Altium Designer on this machine, STAGED, with the rules in the verb (from 0.2.29). stage: preflight / get_installer / launch / wait / license, or... | `altium_install` |  | `fusion_install` |+| `install` | Install Altium Designer on this machine, STAGED, with the rules in the verb (from 0.2.29). stage: preflight / get_installer / launch / wait / license, or... | `altium_install` |  | `fusion_install_fusion` | | `install_extension` | Install, update or remove the AdomBridge .NET extension (the PowerShell installer shipped beside the bridge). Altium must be CLOSED. | `altium_install_extension` |  |  | | `install_receipt` | The last bundle install's full receipt (proof frame included), for a client whose install call outlived ab's budget. | `altium_install_receipt` |  |  | | `instances` | Every running Altium (Designer + Designer Develop can run together). | `altium_instances` |  |  |-| `launch` | Start Altium (the newest numbered install, or the one install names) and wait for its main window, then hand the user's own window back. Answers... | `altium_launch` | `kicad_launch` | `fusion_launch` |+| `launch` | Start Altium (the newest numbered install, or the one install names) and wait for its main window, then hand the user's own window back. Answers... | `altium_launch` | `kicad_launch` | `fusion_start` |+| `library_views` *proposed* | Pictures of library parts for review, each as an image file: the schematic symbol, the footprint (pads and layers), the 3D body seated on the footprint, and... |  |  |  | | `license` | Drive the License Management page (UIA first - no cursor, no foreground). | `altium_license` |  |  | | `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` |  | `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` |  | `fusion_list_commands` |@@ -221,10 +254,10 @@ Driving the application itself (launch, licence, dialogs, windows, views). Each | `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` | | `run_command` | Run an Altium process (Server:Command) through the agent, on the CURRENT document or on filePath opened first. | `altium_run_command` |  | `fusion_run_command` | | `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` |  | `fusion_run_script` |-| `save` | Save the focused document, or open filePath first and save that (WorkspaceManager:SaveObject on the focused document). | `altium_save` | `kicad_save` | `fusion_save` |+| `save` | Save the focused document, or open filePath first and save that (WorkspaceManager:SaveObject on the focused document). | `altium_save` | `kicad_save_board` (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` |  |  |-| `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` |  |+| `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_clear` (partial) | `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_get_selection / kicad_select_items` |  | | `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` |  |  | | `set_layer_visibility` | Show or hide one layer of the current board (by layer id) and refresh the view and the layer tabs. | `altium_set_layer_visibility` |  | `fusion_set_layer_visibility` | | `setup_trial` | Onboarding state machine: from nothing to a working trial. Each call reports the stage it found (install / launch / signin / done) and the ONE next action;... | `altium_setup_trial` |  |  |
package.json+1−1
@@ -1,6 +1,6 @@ {   "slug": "eda-bridge-standard",-  "version": "0.2.1",+  "version": "0.3.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.",
page.json+1−1
@@ -4,7 +4,7 @@   "type": "skill",   "title": "EDA Bridge Standard: one way for an AI to drive every PCB tool",   "brief": "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.",-  "version": "0.2.1",+  "version": "0.3.0",   "hero": {     "type": "billboard",     "headline": "One standard for every EDA bridge",
tools/generate.py+6−6
@@ -126,20 +126,20 @@ def main():     for s in standard:         row = {"name": s["name"], "tier": s["tier"], "source": s["source"]}         for b in bridges:-            if s["name"] in have[b]:-                row[b] = {"verb": prefixes[b] + s["name"], "match": "exact"}-            elif s["name"] in eq.get(b, {}):+            row[b] = None+            # the bridge's own equivalents file comes before a name match: a verb can share a standard name and do+            # another job (kicad_edit_footprint edited placed parts; the standard edit_footprint is the library verb)+            if s["name"] in eq.get(b, {}):                 verb, match = eq[b][s["name"]]                 parts = [strip(p.strip(), prefixes[b]) for p in re.split(r"\s*[/+]\s*", verb)]                 # an equivalent counts only when its verbs are in that bridge's reference catalog                 absent = [p for p in parts if p not in have[b]]                 if absent:                     print(f"warning: {b} {s['name']}: {', '.join(absent)} not in reference/{b}-{bridges[b]['version']}.json, not counted")-                    row[b] = None                 else:                     row[b] = {"verb": " / ".join(prefixes[b] + p for p in parts), "match": match}-            else:-                row[b] = None+            if row[b] is None and s["name"] in have[b]:+                row[b] = {"verb": prefixes[b] + s["name"], "match": "exact"}         coverage.append(row)      meta = {"standard": load("package.json")["version"],
verbs/coverage.json+414−42
@@ -1,10 +1,10 @@ {- "standard": "0.2.1",+ "standard": "0.3.0",  "reference": {   "bridge": "altium",-  "version": "0.2.75"+  "version": "0.2.76"  },- "proposed": 21,+ "proposed": 54,  "compared": {   "kicad": "1.0.62",   "fusion360": "1.12.1"@@ -39,7 +39,10 @@     "verb": "altium_add_models",     "match": "exact"    },-   "kicad": null,+   "kicad": {+    "verb": "kicad_footprint_models",+    "match": "partial"+   },    "fusion360": null   },   {@@ -53,6 +56,17 @@    "kicad": null,    "fusion360": null   },+  {+   "name": "align_parts",+   "tier": "core",+   "source": "proposed",+   "altium": null,+   "kicad": {+    "verb": "kicad_align_footprints",+    "match": "exact"+   },+   "fusion360": null+  },   {    "name": "apply_silkscreen",    "tier": "core",@@ -117,7 +131,24 @@     "match": "exact"    },    "fusion360": {-    "verb": "fusion_board_summary",+    "verb": "fusion_board_info",+    "match": "partial"+   }+  },+  {+   "name": "bodies",+   "tier": "core",+   "source": "proposed",+   "altium": {+    "verb": "altium_bodies",+    "match": "exact"+   },+   "kicad": {+    "verb": "kicad_bodies",+    "match": "exact"+   },+   "fusion360": {+    "verb": "fusion_bodies",     "match": "exact"    }   },@@ -194,6 +225,17 @@    "kicad": null,    "fusion360": null   },+  {+   "name": "copy_routing",+   "tier": "core",+   "source": "proposed",+   "altium": null,+   "kicad": {+    "verb": "kicad_copy_routing",+    "match": "exact"+   },+   "fusion360": null+  },   {    "name": "create_footprint",    "tier": "core",@@ -203,7 +245,7 @@     "match": "exact"    },    "kicad": {-    "verb": "kicad_create_footprint",+    "verb": "kicad_fp_create",     "match": "exact"    },    "fusion360": null@@ -217,7 +259,7 @@     "match": "exact"    },    "kicad": {-    "verb": "kicad_create_symbol",+    "verb": "kicad_sym_create",     "match": "exact"    },    "fusion360": null@@ -233,6 +275,28 @@    "kicad": null,    "fusion360": null   },+  {+   "name": "edit_footprint",+   "tier": "core",+   "source": "proposed",+   "altium": null,+   "kicad": {+    "verb": "kicad_fp_edit",+    "match": "exact"+   },+   "fusion360": null+  },+  {+   "name": "edit_parts",+   "tier": "core",+   "source": "proposed",+   "altium": null,+   "kicad": {+    "verb": "kicad_edit_footprint",+    "match": "exact"+   },+   "fusion360": null+  },   {    "name": "find_symbol",    "tier": "core",@@ -256,11 +320,30 @@     "match": "exact"    },    "kicad": {-    "verb": "kicad_fp_info",+    "verb": "kicad_footprint_graphics",     "match": "partial"    },    "fusion360": null   },+  {+   "name": "generate_body",+   "tier": "core",+   "source": "proposed",+   "altium": null,+   "kicad": null,+   "fusion360": null+  },+  {+   "name": "import_svg",+   "tier": "core",+   "source": "proposed",+   "altium": null,+   "kicad": {+    "verb": "kicad_import_svg",+    "match": "exact"+   },+   "fusion360": null+  },   {    "name": "layer_stack",    "tier": "core",@@ -274,7 +357,7 @@     "match": "exact"    },    "fusion360": {-    "verb": "fusion_layer_stack",+    "verb": "fusion_board_stackup",     "match": "exact"    }   },@@ -369,7 +452,7 @@     "match": "exact"    },    "kicad": {-    "verb": "kicad_move_footprint",+    "verb": "kicad_move_footprint / kicad_flip_footprint",     "match": "exact"    },    "fusion360": {@@ -425,7 +508,7 @@     "match": "exact"    },    "kicad": {-    "verb": "kicad_place_footprint",+    "verb": "kicad_place_footprint / kicad_add_footprint",     "match": "exact"    },    "fusion360": null@@ -469,6 +552,39 @@    "kicad": null,    "fusion360": null   },+  {+   "name": "project_create",+   "tier": "core",+   "source": "proposed",+   "altium": null,+   "kicad": {+    "verb": "kicad_project_create",+    "match": "exact"+   },+   "fusion360": null+  },+  {+   "name": "project_info",+   "tier": "core",+   "source": "proposed",+   "altium": null,+   "kicad": {+    "verb": "kicad_project_info",+    "match": "exact"+   },+   "fusion360": null+  },+  {+   "name": "project_rename",+   "tier": "core",+   "source": "proposed",+   "altium": null,+   "kicad": {+    "verb": "kicad_project_rename",+    "match": "exact"+   },+   "fusion360": null+  },   {    "name": "read_board",    "tier": "core",@@ -486,6 +602,17 @@     "match": "partial"    }   },+  {+   "name": "read_footprint",+   "tier": "core",+   "source": "proposed",+   "altium": null,+   "kicad": {+    "verb": "kicad_fp_info",+    "match": "exact"+   },+   "fusion360": null+  },   {    "name": "read_rules",    "tier": "core",@@ -529,7 +656,7 @@     "match": "exact"    },    "kicad": {-    "verb": "kicad_read_symbol",+    "verb": "kicad_sym_info",     "match": "exact"    },    "fusion360": null@@ -545,6 +672,17 @@    "kicad": null,    "fusion360": null   },+  {+   "name": "remove_graphics",+   "tier": "core",+   "source": "proposed",+   "altium": null,+   "kicad": {+    "verb": "kicad_delete_graphics",+    "match": "exact"+   },+   "fusion360": null+  },   {    "name": "remove_items",    "tier": "core",@@ -562,6 +700,17 @@     "match": "exact"    }   },+  {+   "name": "remove_parts",+   "tier": "core",+   "source": "proposed",+   "altium": null,+   "kicad": {+    "verb": "kicad_delete_footprint",+    "match": "exact"+   },+   "fusion360": null+  },   {    "name": "remove_symbol",    "tier": "core",@@ -571,7 +720,7 @@     "match": "exact"    },    "kicad": {-    "verb": "kicad_remove_symbol",+    "verb": "kicad_sym_delete",     "match": "exact"    },    "fusion360": null@@ -621,7 +770,7 @@     "match": "exact"    },    "kicad": {-    "verb": "kicad_route_net",+    "verb": "kicad_route_net / kicad_add_track",     "match": "exact"    },    "fusion360": {@@ -899,8 +1048,8 @@     "match": "exact"    },    "kicad": {-    "verb": "kicad_sch_sheet_symbol",-    "match": "exact"+    "verb": "kicad_sch_sheet",+    "match": "partial"    },    "fusion360": null   },@@ -965,6 +1114,17 @@    },    "fusion360": null   },+  {+   "name": "set_layer_count",+   "tier": "core",+   "source": "proposed",+   "altium": null,+   "kicad": {+    "verb": "kicad_set_layer_count",+    "match": "exact"+   },+   "fusion360": null+  },   {    "name": "set_models",    "tier": "core",@@ -973,7 +1133,10 @@     "verb": "altium_set_models",     "match": "exact"    },-   "kicad": null,+   "kicad": {+    "verb": "kicad_footprint_models",+    "match": "partial"+   },    "fusion360": null   },   {@@ -1102,7 +1265,7 @@     "match": "exact"    },    "kicad": {-    "verb": "kicad_add_rule",+    "verb": "kicad_custom_rules",     "match": "exact"    },    "fusion360": null@@ -1116,7 +1279,7 @@     "match": "exact"    },    "kicad": {-    "verb": "kicad_annotate",+    "verb": "kicad_sch_annotate",     "match": "exact"    },    "fusion360": null@@ -1134,8 +1297,8 @@     "match": "exact"    },    "fusion360": {-    "verb": "fusion_apply_pours",-    "match": "exact"+    "verb": "fusion_change_pours",+    "match": "partial"    }   },   {@@ -1199,6 +1362,17 @@    "kicad": null,    "fusion360": null   },+  {+   "name": "create_part_project",+   "tier": "native",+   "source": "proposed",+   "altium": null,+   "kicad": {+    "verb": "kicad_make_part_project",+    "match": "partial"+   },+   "fusion360": null+  },   {    "name": "diff_pairs",    "tier": "native",@@ -1223,10 +1397,35 @@     "match": "partial"    },    "fusion360": {-    "verb": "fusion_export_bom",+    "verb": "fusion_export_bom / fusion_board_bom",     "match": "exact"    }   },+  {+   "name": "export_dxf",+   "tier": "native",+   "source": "proposed",+   "altium": null,+   "kicad": {+    "verb": "kicad_export_dxf",+    "match": "exact"+   },+   "fusion360": {+    "verb": "fusion_export_dxf",+    "match": "exact"+   }+  },+  {+   "name": "export_gencad",+   "tier": "native",+   "source": "proposed",+   "altium": null,+   "kicad": {+    "verb": "kicad_export_gencad",+    "match": "exact"+   },+   "fusion360": null+  },   {    "name": "export_gerber",    "tier": "native",@@ -1240,10 +1439,43 @@     "match": "exact"    },    "fusion360": {-    "verb": "fusion_export_gerber",+    "verb": "fusion_export_gerbers",     "match": "exact"    }   },+  {+   "name": "export_ipc2581",+   "tier": "native",+   "source": "proposed",+   "altium": null,+   "kicad": {+    "verb": "kicad_export_ipc2581",+    "match": "exact"+   },+   "fusion360": null+  },+  {+   "name": "export_ipc356",+   "tier": "native",+   "source": "proposed",+   "altium": null,+   "kicad": {+    "verb": "kicad_export_ipc356",+    "match": "exact"+   },+   "fusion360": null+  },+  {+   "name": "export_library_part",+   "tier": "native",+   "source": "proposed",+   "altium": null,+   "kicad": {+    "verb": "kicad_export_part",+    "match": "partial"+   },+   "fusion360": null+  },   {    "name": "export_manufacturing",    "tier": "native",@@ -1253,14 +1485,25 @@     "match": "exact"    },    "kicad": {-    "verb": "kicad_export_manufacturing",-    "match": "exact"+    "verb": "kicad_export_gerber / kicad_export_pos",+    "match": "partial"    },    "fusion360": {     "verb": "fusion_export_gerbers / fusion_export_cpl / fusion_export_bom",     "match": "partial"    }   },+  {+   "name": "export_odb",+   "tier": "native",+   "source": "proposed",+   "altium": null,+   "kicad": {+    "verb": "kicad_export_odb",+    "match": "exact"+   },+   "fusion360": null+  },   {    "name": "export_pdf",    "tier": "native",@@ -1343,7 +1586,7 @@     "match": "exact"    },    "kicad": {-    "verb": "kicad_net_classes",+    "verb": "kicad_netclasses",     "match": "exact"    },    "fusion360": {@@ -1360,7 +1603,7 @@     "match": "exact"    },    "kicad": {-    "verb": "kicad_netlist",+    "verb": "kicad_extract_netlist",     "match": "exact"    },    "fusion360": {@@ -1402,7 +1645,7 @@     "match": "exact"    },    "kicad": {-    "verb": "kicad_pour_state",+    "verb": "kicad_zone_state",     "match": "exact"    },    "fusion360": {@@ -1410,6 +1653,17 @@     "match": "exact"    }   },+  {+   "name": "project_snapshot",+   "tier": "native",+   "source": "proposed",+   "altium": null,+   "kicad": {+    "verb": "kicad_project_snapshot",+    "match": "exact"+   },+   "fusion360": null+  },   {    "name": "remove_pours",    "tier": "native",@@ -1427,6 +1681,28 @@     "match": "exact"    }   },+  {+   "name": "render_board_3d",+   "tier": "native",+   "source": "proposed",+   "altium": null,+   "kicad": {+    "verb": "kicad_render_board",+    "match": "exact"+   },+   "fusion360": null+  },+  {+   "name": "render_board_layers",+   "tier": "native",+   "source": "proposed",+   "altium": null,+   "kicad": {+    "verb": "kicad_export_svg",+    "match": "partial"+   },+   "fusion360": null+  },   {    "name": "render_schematic",    "tier": "native",@@ -1461,7 +1737,7 @@     "match": "exact"    },    "kicad": {-    "verb": "kicad_repour",+    "verb": "kicad_refill_zones",     "match": "exact"    },    "fusion360": {@@ -1604,8 +1880,8 @@     "match": "exact"    },    "kicad": {-    "verb": "kicad_update_pcb",-    "match": "exact"+    "verb": "kicad_update_pcb_from_schematic",+    "match": "partial"    },    "fusion360": null   },@@ -1706,6 +1982,17 @@     "match": "partial"    }   },+  {+   "name": "check_clearance",+   "tier": "checks",+   "source": "proposed",+   "altium": null,+   "kicad": {+    "verb": "kicad_check_clearance",+    "match": "exact"+   },+   "fusion360": null+  },   {    "name": "check_orientation",    "tier": "checks",@@ -1753,6 +2040,17 @@    "kicad": null,    "fusion360": null   },+  {+   "name": "estimate_cost",+   "tier": "checks",+   "source": "proposed",+   "altium": null,+   "kicad": {+    "verb": "kicad_estimate_cost",+    "match": "exact"+   },+   "fusion360": null+  },   {    "name": "fab_check",    "tier": "checks",@@ -1762,7 +2060,7 @@     "match": "exact"    },    "kicad": {-    "verb": "kicad_fab_check",+    "verb": "kicad_validate_for_fab",     "match": "exact"    },    "fusion360": null@@ -1866,6 +2164,17 @@    "kicad": null,    "fusion360": null   },+  {+   "name": "place_decoupling",+   "tier": "checks",+   "source": "proposed",+   "altium": null,+   "kicad": {+    "verb": "kicad_place_decoupling",+    "match": "exact"+   },+   "fusion360": null+  },   {    "name": "placement_check",    "tier": "checks",@@ -1875,11 +2184,33 @@     "match": "exact"    },    "kicad": {-    "verb": "kicad_placement_validate",+    "verb": "kicad_placement_validate / kicad_score_placement",     "match": "partial"    },    "fusion360": null   },+  {+   "name": "plan_fanout",+   "tier": "checks",+   "source": "proposed",+   "altium": null,+   "kicad": {+    "verb": "kicad_plan_fanout",+    "match": "exact"+   },+   "fusion360": null+  },+  {+   "name": "plan_route",+   "tier": "checks",+   "source": "proposed",+   "altium": null,+   "kicad": null,+   "fusion360": {+    "verb": "fusion_plan_route",+    "match": "exact"+   }+  },   {    "name": "read_sheet_file",    "tier": "checks",@@ -1928,7 +2259,7 @@     "match": "exact"    },    "kicad": {-    "verb": "kicad_route_pair",+    "verb": "kicad_route_diff_pair",     "match": "exact"    },    "fusion360": null@@ -2091,6 +2422,17 @@     "match": "exact"    }   },+  {+   "name": "close_all_documents",+   "tier": "app",+   "source": "proposed",+   "altium": null,+   "kicad": null,+   "fusion360": {+    "verb": "fusion_close_all_documents",+    "match": "exact"+   }+  },   {    "name": "close_document",    "tier": "app",@@ -2116,6 +2458,17 @@    "kicad": null,    "fusion360": null   },+  {+   "name": "cross_probe",+   "tier": "app",+   "source": "proposed",+   "altium": null,+   "kicad": {+    "verb": "kicad_cross_probe",+    "match": "exact"+   },+   "fusion360": null+  },   {    "name": "demo",    "tier": "app",@@ -2191,7 +2544,18 @@     "match": "exact"    },    "fusion360": {-    "verb": "fusion_dismiss_dialogs",+    "verb": "fusion_dismiss_blocking_dialogs",+    "match": "exact"+   }+  },+  {+   "name": "document_info",+   "tier": "app",+   "source": "proposed",+   "altium": null,+   "kicad": null,+   "fusion360": {+    "verb": "fusion_document_info",     "match": "exact"    }   },@@ -2249,7 +2613,7 @@    },    "kicad": null,    "fusion360": {-    "verb": "fusion_install",+    "verb": "fusion_install_fusion",     "match": "exact"    }   },@@ -2299,10 +2663,18 @@     "match": "exact"    },    "fusion360": {-    "verb": "fusion_launch",+    "verb": "fusion_start",     "match": "exact"    }   },+  {+   "name": "library_views",+   "tier": "app",+   "source": "proposed",+   "altium": null,+   "kicad": null,+   "fusion360": null+  },   {    "name": "license",    "tier": "app",@@ -2449,8 +2821,8 @@     "match": "exact"    },    "kicad": {-    "verb": "kicad_save",-    "match": "exact"+    "verb": "kicad_save_board",+    "match": "partial"    },    "fusion360": {     "verb": "fusion_save",@@ -2477,8 +2849,8 @@     "match": "exact"    },    "kicad": {-    "verb": "kicad_select_net",-    "match": "exact"+    "verb": "kicad_select_clear",+    "match": "partial"    },    "fusion360": {     "verb": "fusion_select_net",@@ -2494,7 +2866,7 @@     "match": "exact"    },    "kicad": {-    "verb": "kicad_selection",+    "verb": "kicad_get_selection / kicad_select_items",     "match": "exact"    },    "fusion360": null
verbs/standard.json+1414−9
@@ -1,10 +1,10 @@ {- "standard": "0.2.1",+ "standard": "0.3.0",  "reference": {   "bridge": "altium",-  "version": "0.2.75"+  "version": "0.2.76"  },- "proposed": 21,+ "proposed": 54,  "compared": {   "kicad": "1.0.62",   "fusion360": "1.12.1"@@ -147,6 +147,55 @@    "timeoutSeconds": 180,    "unitsNote": "The reference bridge answers this verb in mils (xMil). A bridge following the standard answers in mm under Mm names (xMm)."   },+  {+   "name": "align_parts",+   "tier": "core",+   "source": "proposed",+   "summary": "Line parts up on a common left, right, top, bottom or centre line, or space them evenly, by courtyard box or by anchor point. One undo step, with move_parts' checks.",+   "input": {+    "filePath": "path to the board file (default: the board open in the tool)",+    "expectedRevision": "string: the revision you last read (routing_state); refused with stale_board if the board changed",+    "refs": "[\"C1\", \"C2\", \"C3\"] (required)",+    "mode": "left|right|top|bottom|centerX|centerY|distributeX|distributeY (required)",+    "by": "courtyard|anchor, default courtyard",+    "to": "mm: the line to align on (default from the group)",+    "gapMm": "number: the spacing for distribute (default even spacing between the outer two)",+    "allowOverlap": "bool, default false",+    "allowOutside": "bool, default false",+    "dryRun": "bool, default false: answer the plan and change nothing"+   },+   "output": {+    "targets": "[{ref, x, y}]",+    "mismatches": "[{ref, asked, got}]",+    "revision": "string: the board's new revision"+   },+   "hint": "Without to, left takes the group's smallest x, right the largest, top the highest edge and bottom the lowest (y up); centre lines take the mean. distribute keeps the outer two in place.",+   "pitfalls": [+    "Rotation and side are kept: align parts of the same orientation for a clean row.",+    "A courtyard collision or a part off the board is refused, as in move_parts."+   ],+   "related": [+    "move_parts",+    "placement_check"+   ],+   "example": {+    "filePath": "C:/proj/Board.PcbDoc",+    "refs": [+     "C4",+     "C5",+     "C6"+    ],+    "mode": "top",+    "expectedRevision": "<rev>"+   },+   "longRunning": true,+   "timeoutSeconds": 130,+   "proposedBy": "kicad-lane",+   "since": "0.3.0",+   "agreedBy": [+    "altium-lane"+   ]+  },   {    "name": "apply_silkscreen",    "tier": "core",@@ -296,6 +345,48 @@    "longRunning": false,    "timeoutSeconds": 120   },+  {+   "name": "bodies",+   "tier": "core",+   "source": "proposed",+   "summary": "Every part's 3D body as a box: its footprint rectangle on the board and its height range above the surface it sits on (a bottom part measures down from the bottom). Names the parts with no 3D body and the ones whose body is not where the board puts the part. Read only.",+   "input": {+    "filePath": "path to the board (optional; default the open board)",+    "refs": "[ref] (default every part)"+   },+   "output": {+    "bodies": "[{ref, side: top|bottom, x0, y0, x1, y1, z0, z1}]: the bodies companion (schema/companions.schema.json), mm",+    "noBody": "[ref]: parts with no 3D body, so no height",+    "suspect": "[{ref, why: [string]}]: a body off its footprint, floating above the board or sunk into it",+    "tallest": "{top: {ref, heightMm}, bottom: {ref, heightMm}}",+    "surfaceZMm": "{top, bottom}: the z of each board surface",+    "revision": "string"+   },+   "hint": "The rows are the bodies companion, which height_check, placement_check and enclosure checks read. One box per body and one box per part are both valid; checks take the union per part.",+   "pitfalls": [+    "A part whose library has no 3D model is in noBody: it has no height, not a height of 0.",+    "A body in suspect usually comes from a wrong or offset library model: fix it before trusting its height."+   ],+   "related": [+    "height_check",+    "placement_check",+    "add_body",+    "render_board_3d"+   ],+   "example": {+    "refs": [+     "U1",+     "J2"+    ]+   },+   "longRunning": false,+   "timeoutSeconds": 120,+   "proposedBy": "fusion-lane",+   "since": "0.3.0",+   "agreedBy": [+    "altium-lane"+   ]+  },   {    "name": "clone_symbol",    "tier": "core",@@ -444,6 +535,68 @@    "longRunning": false,    "timeoutSeconds": 90   },+  {+   "name": "copy_routing",+   "tier": "core",+   "source": "proposed",+   "summary": "Copy the tracks and vias inside a box to an offset, remapping nets by pairing parts (a designator map or pattern), so a repeated channel gets the same routing. One undo step.",+   "input": {+    "filePath": "path to the board file (default: the board open in the tool)",+    "expectedRevision": "string: the revision you last read (routing_state); refused with stale_board if the board changed",+    "box": "[x1, y1, x2, y2] mm (required): the source",+    "offset": "[dx, dy] mm (required)",+    "refMap": "{\"U1\": \"U5\"}: pair parts, so each pad's net maps to the partner pad's net",+    "refPattern": "{from: \"CH1_*\", to: \"CH2_*\"}: pair parts by designator pattern",+    "netMap": "{\"SIG\": \"SIG2\"}: overrides",+    "keepUnmappedNets": "bool, default false",+    "layers": "[layer]: copy only these",+    "validate": "bool, default true: run the tool's DRC on the result before committing",+    "dryRun": "bool, default false: answer the plan and change nothing"+   },+   "output": {+    "copied": "{tracks: int, vias: int}",+    "netMap": "{from: to}: the pairing used",+    "skipped": "[{item, why}]",+    "drc": "{ran, newErrors}",+    "revision": "string: the board's new revision"+   },+   "hint": "A track is copied when both ends are in the box, a via when its centre is. Without a remap the copy keeps its nets. Dry-run first and check netMap.",+   "pitfalls": [+    "Only through vias are copied: blind and buried vias are skipped.",+    "The copy connects only where the target pads sit at the same offset: place the target channel identically first (replicate_layout).",+    "One source net mapping to two target nets is refused (net_map_conflict) unless netMap settles it."+   ],+   "related": [+    "replicate_layout",+    "route_net",+    "routing_state"+   ],+   "example": {+    "filePath": "C:/proj/Board.PcbDoc",+    "box": [+     10,+     10,+     30,+     25+    ],+    "offset": [+     25,+     0+    ],+    "refPattern": {+     "from": "CH1_*",+     "to": "CH2_*"+    },+    "expectedRevision": "<rev>"+   },+   "longRunning": true,+   "timeoutSeconds": 130,+   "proposedBy": "kicad-lane",+   "since": "0.3.0",+   "agreedBy": [+    "altium-lane"+   ]+  },   {    "name": "create_footprint",    "tier": "core",@@ -554,6 +707,104 @@    "longRunning": false,    "timeoutSeconds": 60   },+  {+   "name": "edit_footprint",+   "tier": "core",+   "source": "proposed",+   "summary": "Edit a library footprint in place: change, delete, add or renumber pads; add, replace or delete graphics on a layer; set its description, tags and attributes; replace, add or delete 3D models. Everything not edited stays as it was.",+   "input": {+    "libraryPath": "path to the footprint library (required)",+    "name": "the footprint's name (required)",+    "pads": "[{number, set?: {sizeMm, at, shape, drillMm, layers, rotation, type, newNumber}, delete?: true}]",+    "addPads": "[pad]",+    "renumber": "{map: {\"1\": \"A1\"}} | {sequential: true, start?: 1}",+    "graphics": "[{layer, mode: append|replace|delete, widthMm?, shapes: [{type: line|arc|rect|circle|poly, ...}]}]",+    "metadata": "{description?, tags?, attributes?: {mount, excludeFromBom, excludeFromPos, dnp}}",+    "models": "{mode: replace|append|delete, list: [{path, offset, scale, rotate}]}",+    "dryRun": "bool, default false: answer the plan and change nothing"+   },+   "output": {+    "changes": "[string]: what was done, in order"+   },+   "hint": "Operations run in the order pads, addPads, renumber, graphics, metadata, models. An edited pad keeps its id.",+   "pitfalls": [+    "Boards that already use the footprint keep their own copy: update them with swap_footprint.",+    "Graphics replace and delete touch shapes only, never text on that layer."+   ],+   "related": [+    "read_footprint",+    "create_footprint",+    "swap_footprint",+    "add_body"+   ],+   "example": {+    "libraryPath": "C:/lib/Mine.PcbLib",+    "name": "SOT-23_Mine",+    "pads": [+     {+      "number": "1",+      "set": {+       "sizeMm": [+        1.0,+        0.8+       ]+      }+     }+    ]+   },+   "longRunning": false,+   "timeoutSeconds": 30,+   "proposedBy": "kicad-lane",+   "since": "0.3.0",+   "agreedBy": [+    "altium-lane"+   ]+  },+  {+   "name": "edit_parts",+   "tier": "core",+   "source": "proposed",+   "summary": "Edit placed parts: value, designator, any field (add, change, remove), do-not-populate, exclusion from the BOM or position files, mounting type and the lock. One undo step.",+   "input": {+    "filePath": "path to the board file (default: the board open in the tool)",+    "expectedRevision": "string: the revision you last read (routing_state); refused with stale_board if the board changed",+    "edits": "[{ref, value?, newRef?, fields?: {name: value | null (remove)}, dnp?: bool, excludeFromBom?: bool, excludeFromPos?: bool, mount?: smd|through_hole|other, locked?: bool}] (required)",+    "dryRun": "bool, default false: answer the plan and change nothing"+   },+   "output": {+    "edited": "[{ref, before, after}]",+    "failed": "[{ref, error}]",+    "revision": "string: the board's new revision"+   },+   "hint": "Fields the tool requires (designator, value) cannot be removed. Read the parts first with component_data.",+   "pitfalls": [+    "Board-side edits of what the schematic owns are lost at the next update_pcb: change the schematic instead (sch_edit).",+    "A designator already taken is refused."+   ],+   "related": [+    "component_data",+    "part_parameters",+    "sch_edit"+   ],+   "example": {+    "filePath": "C:/proj/Board.PcbDoc",+    "edits": [+     {+      "ref": "R7",+      "value": "4k7",+      "dnp": true+     }+    ],+    "expectedRevision": "<rev>"+   },+   "longRunning": true,+   "timeoutSeconds": 130,+   "proposedBy": "kicad-lane",+   "since": "0.3.0",+   "agreedBy": [+    "altium-lane"+   ]+  },   {    "name": "find_symbol",    "tier": "core",@@ -613,6 +864,115 @@    "longRunning": false,    "timeoutSeconds": 120   },+  {+   "name": "generate_body",+   "tier": "core",+   "source": "proposed",+   "summary": "Make a part's 3D body from its package family and its datasheet dimensions (chip, SOIC, QFN, QFP, BGA, SOT-23, DFN, MELF, electrolytic can, crystal, pin header and others), to IPC-7351 proportions, optionally with a marking on its top, and write it as a STEP file.",+   "input": {+    "family": "chip | soic | qfn | qfp | bga | sot23 | dfn | melf | ecap | crystal | header and others (required; an unknown one is answered with the families the bridge supports)",+    "dimensionsMm": "{letter: mm}: the package drawing's JEDEC letters (A height, D body length, E lead span, E1 body width, b lead width, e pitch, L lead length) plus pins; a missing one takes the family's default",+    "marking": "text on the top face (an MPN or a value code); a newline starts a second line",+    "markingStyle": "raised | engraved (default raised)",+    "outputPath": "the .step file to write (required)"+   },+   "output": {+    "stepPath": "path",+    "family": "string",+    "dimensionsMm": "{letter: mm}: every dimension used, defaults included",+    "bboxMm": "{x, y, z}",+    "marking": "string | null",+    "families": "[string] (when family is unknown)"+   },+   "hint": "The body is in the package's own frame (IPC-7351 zero orientation, seated on z = 0), ready for add_body. Compare bboxMm with the datasheet's body size before attaching it.",+   "pitfalls": [+    "A wrong dimension gives a plausible but wrong body: nothing checks it against a datasheet.",+    "A marking is real geometry: very small text on a small package is unreadable, which is not an error."+   ],+   "related": [+    "add_body",+    "bodies",+    "height_check",+    "library_views"+   ],+   "example": {+    "family": "soic",+    "dimensionsMm": {+     "pins": 8,+     "D": 4.9,+     "E": 6.0,+     "E1": 3.9,+     "A": 1.75,+     "e": 1.27+    },+    "marking": "LM358",+    "outputPath": "C:/parts/LM358.step"+   },+   "longRunning": false,+   "timeoutSeconds": 120,+   "proposedBy": "fusion-lane",+   "since": "0.3.0",+   "agreedBy": [+    "altium-lane"+   ]+  },+  {+   "name": "import_svg",+   "tier": "core",+   "source": "proposed",+   "summary": "Import SVG artwork (a logo, a label) as filled polygons on a silkscreen, copper, mask or user layer, at a position and size; curves flattened, holes kept. One undo step.",+   "input": {+    "filePath": "path to the board file (default: the board open in the tool)",+    "expectedRevision": "string: the revision you last read (routing_state); refused with stale_board if the board changed",+    "svgPath": "path to the .svg",+    "svg": "the SVG text (instead of svgPath)",+    "at": "[x, y] mm (required)",+    "widthMm": "number: the artwork's width (or scale)",+    "scale": "number, default 1",+    "anchor": "topleft|center, default topleft: which point of the artwork at names",+    "layer": "default F.SilkS",+    "mirror": "bool, default true on bottom layers",+    "net": "a net for artwork on copper",+    "toleranceMm": "number, default 0.02: curve flattening",+    "dryRun": "bool, default false: answer the plan and change nothing"+   },+   "output": {+    "polygons": "int",+    "sizeMm": "[w, h]",+    "ids": "[id]",+    "skipped": "[{element, why}]",+    "revision": "string: the board's new revision"+   },+   "hint": "Filled shapes import; text and images are listed in skipped (convert text to paths first). A shape inside another becomes a hole.",+   "pitfalls": [+    "Stroke-only artwork imports nothing: give the SVG filled shapes.",+    "On copper the shapes are graphics: give net to tie them to a net, and run run_drc.",+    "On a bottom layer the artwork is mirrored so it reads correctly from the back; mirror:false keeps it as drawn."+   ],+   "related": [+    "apply_silkscreen",+    "silk_state",+    "run_drc"+   ],+   "example": {+    "filePath": "C:/proj/Board.PcbDoc",+    "svgPath": "C:/proj/logo.svg",+    "at": [+     120,+     95+    ],+    "widthMm": 10,+    "layer": "F.SilkS",+    "expectedRevision": "<rev>"+   },+   "longRunning": true,+   "timeoutSeconds": 130,+   "proposedBy": "kicad-lane",+   "since": "0.3.0",+   "agreedBy": [+    "altium-lane"+   ]+  },   {    "name": "layer_stack",    "tier": "core",@@ -770,21 +1130,21 @@    "name": "move_parts",    "tier": "core",    "source": "altium",-   "summary": "Move and rotate placed components; each part is read back to 0.001 mm and the exact rotation. One undo step.",+   "summary": "Move, rotate and flip placed components (side top or bottom; flip:true turns a part over); each part is read back to 0.001 mm, the exact rotation and its side. One undo step.",    "input": {     "boardId": "string (optional) - refused with board_mismatch unless this is the current board",     "expectPath": "string (optional)",     "expectedRevision": "string (optional) - the revision you last read; refused with stale_board if the board changed",-    "parts": "[{ref, x, y, rotation}] - mm and degrees, Altium's frame; or {ref, dx, dy} to move by an offset; rotation kept when left out"+    "parts": "[{ref, x, y, rotation, side?: top|bottom, flip?: bool}] - mm and degrees, Altium's frame; or {ref, dx, dy} to move by an offset; rotation and side kept when left out"    },    "output": {     "mismatches": "[{ref, asked, got}] when a part did not land where asked (errorCode readback_mismatch)",     "results": "[ok|err:...]",     "revision": "string"    },-   "hint": "Rotation is absolute, not a delta.",+   "hint": "Rotation is absolute, not a delta. A part flipped to the bottom is mirrored by Altium; give the rotation you want as seen from the top.",    "pitfalls": [-    "Moving to the other side of the board is not supported yet."+    "Flipping a part leaves its tracks where they were: they no longer reach its pads on the other side. Re-route after a flip."    ],    "related": [     "routing_state",@@ -1029,6 +1389,121 @@    "longRunning": false,    "timeoutSeconds": 90   },+  {+   "name": "project_create",+   "tier": "core",+   "source": "proposed",+   "summary": "Create a new project folder with a project file, an empty schematic and an empty board (2 to 32 copper layers), with a title and text variables.",+   "input": {+    "parentDir": "folder to create the project in (required)",+    "name": "string (required): the project and folder name",+    "title": "string",+    "layers": "int, default 2",+    "fabRules": "a fab name from adom/pcb-design-rules, recorded to apply once the board has content",+    "textVariables": "{\"REV\": \"A\"}",+    "dryRun": "bool, default false: answer the plan and change nothing"+   },+   "output": {+    "project": "path",+    "files": "[path]"+   },+   "hint": "Next: draw the outline (set_outline), then place and route. fabRules is recorded, not applied.",+   "pitfalls": [+    "A folder that already holds a project is refused.",+    "The board has no outline yet: set it before routing or exporting."+   ],+   "related": [+    "project_info",+    "sch_create",+    "set_outline"+   ],+   "example": {+    "parentDir": "C:/Users/me/Documents/Projects",+    "name": "widget",+    "layers": 4+   },+   "longRunning": false,+   "timeoutSeconds": 30,+   "proposedBy": "kicad-lane",+   "since": "0.3.0",+   "agreedBy": [+    "altium-lane"+   ]+  },+  {+   "name": "project_info",+   "tier": "core",+   "source": "proposed",+   "summary": "A project at a glance: name, files with sizes and dates, the sheet tree, the board (layers, parts, nets, size), text variables, net classes, last change, and whether the tool has it open. Read only.",+   "input": {+    "project": "path to the project file, its folder or any of its documents (required)"+   },+   "output": {+    "name": "string",+    "files": "[{path, bytes, modified}]",+    "sheets": "the sheet tree, as sch_hierarchy answers it",+    "board": "{layers, parts, nets, sizeMm}",+    "textVariables": "{name: value}",+    "netClasses": "[string]",+    "modified": "date",+    "open": "bool: the tool has a document of this project open"+   },+   "hint": "Read this before renaming, snapshotting or editing a project.",+   "pitfalls": [],+   "related": [+    "sch_hierarchy",+    "board_summary",+    "open_project"+   ],+   "example": {+    "project": "C:/proj/Board.PrjPcb"+   },+   "longRunning": false,+   "timeoutSeconds": 30,+   "proposedBy": "kicad-lane",+   "since": "0.3.0",+   "agreedBy": [+    "altium-lane"+   ]+  },+  {+   "name": "project_rename",+   "tier": "core",+   "source": "proposed",+   "summary": "Rename a project: the project file, the root sheet, the board and the tool's side files, with the references inside them updated. Refused while the tool has the project open.",+   "input": {+    "project": "path to the project file (required)",+    "newName": "string (required)",+    "dryRun": "bool, default false: answer the plan and change nothing"+   },+   "output": {+    "renamed": "[{from, to}]",+    "changed": "[{file, what}]"+   },+   "hint": "Dry-run first: the plan lists every file renamed and what changes inside each. Close the project in the tool first.",+   "pitfalls": [+    "Child sheet files keep their names; only the documents named after the project are renamed.",+    "The folder keeps its name.",+    "Take a project_snapshot first if the project is not under version control."+   ],+   "related": [+    "project_snapshot",+    "project_info",+    "close"+   ],+   "example": {+    "project": "C:/proj/Old.PrjPcb",+    "newName": "widget-v2",+    "dryRun": true+   },+   "longRunning": false,+   "timeoutSeconds": 60,+   "proposedBy": "kicad-lane",+   "since": "0.3.0",+   "agreedBy": [+    "altium-lane"+   ]+  },   {    "name": "read_board",    "tier": "core",@@ -1055,6 +1530,46 @@    "longRunning": false,    "timeoutSeconds": 120   },+  {+   "name": "read_footprint",+   "tier": "core",+   "source": "proposed",+   "summary": "Every detail of one library footprint: pads (number, type, shape, position, size, drill, layers), the layers it uses, its courtyard box, graphics per layer, attributes, properties and 3D models. The library mirror of read_symbol; footprint_primitives reads a part placed on the board.",+   "input": {+    "libraryPath": "path to the footprint library",+    "name": "the footprint's name (with libraryPath)",+    "libId": "\"Lib:Name\": resolved through the project's and then the global library table",+    "project": "path to the project, for libId"+   },+   "output": {+    "name": "string",+    "pads": "[{number, type, shape, at, sizeMm, drillMm, layers, rotation}]",+    "layers": "[string]",+    "courtyardMm": "[x1, y1, x2, y2]",+    "graphics": "{layer: count}",+    "attributes": "{mount, excludeFromBom, excludeFromPos, dnp}",+    "properties": "{name: value}",+    "models": "[{path, offset, scale, rotate}]"+   },+   "hint": "Read before edit_footprint, and to check pin 1 and the pad numbers against the symbol.",+   "pitfalls": [],+   "related": [+    "edit_footprint",+    "read_symbol",+    "footprint_primitives",+    "list_library"+   ],+   "example": {+    "libId": "Package_SO:SOIC-8_3.9x4.9mm_P1.27mm"+   },+   "longRunning": false,+   "timeoutSeconds": 60,+   "proposedBy": "kicad-lane",+   "since": "0.3.0",+   "agreedBy": [+    "altium-lane"+   ]+  },   {    "name": "read_rules",    "tier": "core",@@ -1173,6 +1688,46 @@    "longRunning": false,    "timeoutSeconds": 90   },+  {+   "name": "remove_graphics",+   "tier": "core",+   "source": "proposed",+   "summary": "Remove board graphics (lines, rectangles, circles, arcs, polygons, texts, dimensions) by id, or every one on a layer and of a kind. One undo step.",+   "input": {+    "filePath": "path to the board file (default: the board open in the tool)",+    "expectedRevision": "string: the revision you last read (routing_state); refused with stale_board if the board changed",+    "ids": "[id]",+    "layer": "\"F.SilkS\": every graphic on this layer",+    "kinds": "[line|rect|circle|arc|polygon|text|dimension]",+    "dryRun": "bool, default false: answer the plan and change nothing"+   },+   "output": {+    "removed": "[{id, kind, layer, points}]",+    "revision": "string: the board's new revision"+   },+   "hint": "Board-level graphics only; graphics inside parts are footprint_primitives. An unknown id refuses the whole call (unknown_ids).",+   "pitfalls": [+    "Removing Edge.Cuts graphics removes the board outline.",+    "A layer or kind filter without ids removes every match: dry-run it first."+   ],+   "related": [+    "remove_items",+    "footprint_primitives",+    "silk_state"+   ],+   "example": {+    "filePath": "C:/proj/Board.PcbDoc",+    "layer": "Dwgs.User",+    "dryRun": true+   },+   "longRunning": true,+   "timeoutSeconds": 130,+   "proposedBy": "kicad-lane",+   "since": "0.3.0",+   "agreedBy": [+    "altium-lane"+   ]+  },   {    "name": "remove_items",    "tier": "core",@@ -1208,6 +1763,48 @@    "longRunning": false,    "timeoutSeconds": 300   },+  {+   "name": "remove_parts",+   "tier": "core",+   "source": "proposed",+   "summary": "Remove placed parts from the board by designator, as one undo step. The library is not touched (that is remove_footprint).",+   "input": {+    "filePath": "path to the board file (default: the board open in the tool)",+    "expectedRevision": "string: the revision you last read (routing_state); refused with stale_board if the board changed",+    "refs": "[\"R7\", \"R8\"] (required)",+    "allowLocked": "bool, default false",+    "dryRun": "bool, default false: answer the plan and change nothing"+   },+   "output": {+    "removed": "[{ref, nets: [string]}]",+    "failed": "[{ref, error}]",+    "revision": "string: the board's new revision"+   },+   "hint": "Each removed part lists the nets its pads carried. A locked part is refused (part_locked) unless allowLocked:true.",+   "pitfalls": [+    "Tracks and vias that met the pads stay: routing_state shows what is left dangling.",+    "A part still in the schematic comes back at the next update_pcb."+   ],+   "related": [+    "move_parts",+    "routing_state",+    "update_pcb"+   ],+   "example": {+    "filePath": "C:/proj/Board.PcbDoc",+    "refs": [+     "TP3"+    ],+    "expectedRevision": "<rev>"+   },+   "longRunning": true,+   "timeoutSeconds": 130,+   "proposedBy": "kicad-lane",+   "since": "0.3.0",+   "agreedBy": [+    "altium-lane"+   ]+  },   {    "name": "remove_symbol",    "tier": "core",@@ -1402,22 +1999,25 @@     "expectPath": "string (optional) - refuse with wrong_board unless this .PcbDoc is the current board"    },    "output": {+    "altiumRatsnest": "int - Altium's own count",     "boardId": "string (the .PcbDoc path)",     "components": "[{ref, x, y, rotation, side, pattern}]",     "counts": "{tracks, arcs, vias, pads, components, polygons, nets}",+    "isolatedCopper": "[{net, layer, at{x,y}}] - pours that touch nothing else of their net: not counted in unconnected",     "outline": "[[x,y]]",     "pads": "[{ref, name, x, y, sizeX, sizeY, rotation, layer, drill, net}]",     "polygons": "[{net, layer, points[[x,y]]}]",     "revision": "string - pass as expectedRevision to the edit verbs",+    "splitNets": "[{net, groups}]",     "tracks": "[{start{x,y}, end{x,y}, width, layer, net}]",-    "unconnected": "int",+    "unconnected": "int - connections still to make, from the copper",     "vias": "[{position{x,y}, size, drill, layers[2], net}]"    },    "hint": "Layers use KiCad names (F.Cu, B.Cu, In<n>.Cu; *.Cu = a multi-layer pad) with Altium's layerId alongside. Coordinates are Altium's own frame (y up), in mm. This is the read AI Flow's Altium lane calls before and after every edit.",    "pitfalls": [     "Needs a .PcbDoc current (altium_show_2d_board {filePath}).",     "Footprint-internal tracks and arcs are left out; only free copper is listed.",-    "unconnected counts Altium's ratsnest lines: re-read after an edit for a fresh count."+    "unconnected is computed from the copper (Altium's ratsnest skips parts off the board; its count rides along as altiumRatsnest). A pour that reaches nothing else of its net is listed under isolatedCopper and not counted. Re-read after an edit for a fresh count."    ],    "related": [     "read_board",@@ -2590,6 +3190,45 @@    "timeoutSeconds": 120,    "unitsNote": "The reference bridge answers this verb in mils (xMil). A bridge following the standard answers in mm under Mm names (xMm)."   },+  {+   "name": "set_layer_count",+   "tier": "core",+   "source": "proposed",+   "summary": "Set the board's copper layer count (2, 4, 6 or 8): the layer table and the stack-up, keeping the board thickness.",+   "input": {+    "filePath": "path to the board file (default: the board open in the tool)",+    "count": "2|4|6|8 (required)",+    "expectedRevision": "string: the revision you last read (routing_state); refused with stale_board if the board changed",+    "dryRun": "bool, default false: answer the plan and change nothing"+   },+   "output": {+    "layers": "[string]: the copper layers now",+    "stackup": "the new stack-up, as layer_stack answers it",+    "revision": "string: the board's new revision"+   },+   "hint": "New inner layers are signal layers In1.Cu ... Read the result with layer_stack.",+   "pitfalls": [+    "A layer being removed that still carries copper or graphics is refused (layers_in_use, with the counts per layer).",+    "New dielectrics are generic: re-check an impedance-controlled stack-up with layer_stack.",+    "Net classes and design rules are not changed."+   ],+   "related": [+    "layer_stack",+    "copper_layers",+    "layers_in_use"+   ],+   "example": {+    "filePath": "C:/proj/Board.PcbDoc",+    "count": 4+   },+   "longRunning": false,+   "timeoutSeconds": 60,+   "proposedBy": "kicad-lane",+   "since": "0.3.0",+   "agreedBy": [+    "altium-lane"+   ]+  },   {    "name": "set_models",    "tier": "core",@@ -3307,6 +3946,45 @@    "longRunning": false,    "timeoutSeconds": 120   },+  {+   "name": "create_part_project",+   "tier": "native",+   "source": "proposed",+   "summary": "Generate a small real project (schematic and board) around one library part, so the part can be shown and tested in every view: schematic, 2D board and 3D board.",+   "input": {+    "part": "the part's symbol name or library id (required)",+    "footprint": "a footprint name (default the symbol's own)",+    "projectName": "string (default from the part)",+    "outputDir": "folder (default the user's projects folder)",+    "overwrite": "bool, default false: replace a project of that name"+   },+   "output": {+    "project": "path",+    "schematic": "path",+    "board": "path"+   },+   "hint": "The board keeps the footprint's 3D model, so render_board_3d and show_3d_board show the real part. One part by design.",+   "pitfalls": [+    "The part's symbol and footprint must both be in a library the tool can find.",+    "An existing project of that name is refused unless overwrite:true."+   ],+   "related": [+    "export_library_part",+    "render_board_3d",+    "show_3d_board",+    "import_part"+   ],+   "example": {+    "part": "IN-S42ATR"+   },+   "longRunning": true,+   "timeoutSeconds": 130,+   "proposedBy": "kicad-lane",+   "since": "0.3.0",+   "agreedBy": [+    "altium-lane"+   ]+  },   {    "name": "diff_pairs",    "tier": "native",@@ -3377,6 +4055,83 @@    "longRunning": false,    "timeoutSeconds": 300   },+  {+   "name": "export_dxf",+   "tier": "native",+   "source": "proposed",+   "summary": "Export chosen board layers to DXF, one file per layer (the outline, panel drawings, stencils, enclosure work).",+   "input": {+    "filePath": "path to the board file (default: the board open in the tool)",+    "layers": "[\"Edge.Cuts\", \"F.Cu\"]: layer names (required; there is no sensible default)",+    "outputDir": "folder for the output (default beside the board)",+    "units": "mm|in, default mm",+    "contours": "bool, default false: join outline segments into polylines (most CAM and laser tools want it)",+    "titleBlock": "bool, default false",+    "excludeDesignators": "bool, default false",+    "excludeValues": "bool, default false",+    "useDrillOrigin": "bool, default false"+   },+   "output": {+    "files": "[{layer, path}]"+   },+   "hint": "One file per layer, named after the board and the layer. For an enclosure drawing export Edge.Cuts with contours:true.",+   "pitfalls": [+    "The board's DXF only: a mechanical DXF of a 3D design is a different job and not this verb."+   ],+   "related": [+    "render_board_layers",+    "export_step"+   ],+   "example": {+    "filePath": "C:/proj/Board.PcbDoc",+    "layers": [+     "Edge.Cuts"+    ],+    "contours": true+   },+   "longRunning": true,+   "timeoutSeconds": 300,+   "proposedBy": "kicad-lane",+   "since": "0.3.0",+   "agreedBy": [+    "altium-lane"+   ]+  },+  {+   "name": "export_gencad",+   "tier": "native",+   "source": "proposed",+   "summary": "Export the board as GenCAD 1.4, the input of test-fixture tools and some assembly houses' CAM.",+   "input": {+    "filePath": "path to the board file (default: the board open in the tool)",+    "outputDir": "folder for the output (default beside the board)",+    "uniquePins": "bool, default false: rename duplicate pad numbers (several fixture tools need it)",+    "flipBottomPads": "bool, default false",+    "useDrillOrigin": "bool, default false: coordinates from the drill origin instead of the board's origin"+   },+   "output": {+    "file": "path"+   },+   "hint": "Ask the fixture or assembly house which options it needs; uniquePins is the common one.",+   "pitfalls": [+    "Run run_drc first: the file carries the board's errors with it."+   ],+   "related": [+    "export_manufacturing",+    "export_ipc356"+   ],+   "example": {+    "filePath": "C:/proj/Board.PcbDoc",+    "uniquePins": true+   },+   "longRunning": true,+   "timeoutSeconds": 300,+   "proposedBy": "kicad-lane",+   "since": "0.3.0",+   "agreedBy": [+    "altium-lane"+   ]+  },   {    "name": "export_gerber",    "tier": "native",@@ -3414,6 +4169,111 @@    "longRunning": false,    "timeoutSeconds": 300   },+  {+   "name": "export_ipc2581",+   "tier": "native",+   "source": "proposed",+   "summary": "Export the board as IPC-2581: one XML file with copper, drill, stack-up, netlist and BOM, through the tool's own exporter.",+   "input": {+    "filePath": "path to the board file (default: the board open in the tool)",+    "outputDir": "folder for the output (default beside the board)",+    "version": "B|C, default C",+    "units": "mm|in, default mm",+    "compress": "bool, default false: zip the XML",+    "bomFields": "{mpn, manufacturer, distributorPn, distributor}: the part field names that carry these, so the embedded BOM is useful to the fab"+   },+   "output": {+    "file": "path"+   },+   "hint": "Name the part fields with bomFields, or the BOM inside the file carries no part numbers.",+   "pitfalls": [+    "Run run_drc first: the file carries the board's errors with it."+   ],+   "related": [+    "export_odb",+    "export_manufacturing",+    "run_drc"+   ],+   "example": {+    "filePath": "C:/proj/Board.PcbDoc",+    "bomFields": {+     "mpn": "MPN"+    }+   },+   "longRunning": true,+   "timeoutSeconds": 300,+   "proposedBy": "kicad-lane",+   "since": "0.3.0",+   "agreedBy": [+    "altium-lane"+   ]+  },+  {+   "name": "export_ipc356",+   "tier": "native",+   "source": "proposed",+   "summary": "Export the IPC-D-356 netlist of the board, for bare-board electrical test (flying probe or bed of nails).",+   "input": {+    "filePath": "path to the board file (default: the board open in the tool)",+    "outputDir": "folder for the output (default beside the board)"+   },+   "output": {+    "file": "path"+   },+   "hint": "Send it with the Gerbers when the fab tests boards against the netlist.",+   "pitfalls": [+    "Run run_drc first: the file carries the board's errors with it."+   ],+   "related": [+    "export_manufacturing",+    "netlist"+   ],+   "example": {+    "filePath": "C:/proj/Board.PcbDoc"+   },+   "longRunning": true,+   "timeoutSeconds": 300,+   "proposedBy": "kicad-lane",+   "since": "0.3.0",+   "agreedBy": [+    "altium-lane"+   ]+  },+  {+   "name": "export_library_part",+   "tier": "native",+   "source": "proposed",+   "summary": "Export one library part into its own small library files: a symbol library with only its symbol, a footprint library with only its footprint, and its 3D model file.",+   "input": {+    "part": "the part's symbol name or library id (required)",+    "footprint": "a footprint name (default the symbol's own)",+    "what": "[symbol, footprint, model] (default all three)",+    "outputDir": "folder for the files"+   },+   "output": {+    "exports": "{symbol: path, footprint: path, model: path}",+    "missing": "[what]"+   },+   "hint": "Use it to hand one part to another project or another tool.",+   "pitfalls": [+    "success is false when any piece asked for is missing; exports still carries what was written."+   ],+   "related": [+    "read_symbol",+    "read_footprint",+    "import_part"+   ],+   "example": {+    "part": "IN-S42ATA"+   },+   "longRunning": true,+   "timeoutSeconds": 130,+   "proposedBy": "kicad-lane",+   "since": "0.3.0",+   "agreedBy": [+    "altium-lane"+   ]+  },   {    "name": "export_manufacturing",    "tier": "native",@@ -3453,6 +4313,41 @@    "longRunning": false,    "timeoutSeconds": 600   },+  {+   "name": "export_odb",+   "tier": "native",+   "source": "proposed",+   "summary": "Export the board as ODB++ (copper, drill, stack-up, netlist and parts in one archive) through the tool's own exporter.",+   "input": {+    "filePath": "path to the board file (default: the board open in the tool)",+    "outputDir": "folder for the output (default beside the board)",+    "units": "mm|in, default mm",+    "compression": "zip|tgz|none, default zip"+   },+   "output": {+    "files": "[path]",+    "outputDir": "path"+   },+   "hint": "Send the archive to a fab that takes ODB++ instead of Gerbers. export_manufacturing makes the Gerber set.",+   "pitfalls": [+    "Run run_drc first: the file carries the board's errors with it."+   ],+   "related": [+    "export_manufacturing",+    "export_ipc2581",+    "run_drc"+   ],+   "example": {+    "filePath": "C:/proj/Board.PcbDoc"+   },+   "longRunning": true,+   "timeoutSeconds": 300,+   "proposedBy": "kicad-lane",+   "since": "0.3.0",+   "agreedBy": [+    "altium-lane"+   ]+  },   {    "name": "export_pdf",    "tier": "native",@@ -3828,6 +4723,42 @@    "longRunning": false,    "timeoutSeconds": 180   },+  {+   "name": "project_snapshot",+   "tier": "native",+   "source": "proposed",+   "summary": "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.",+   "input": {+    "project": "path to the project file (required)",+    "label": "string: added to the folder name",+    "pdfs": "bool, default true"+   },+   "output": {+    "folder": "path",+    "files": "[path]",+    "pdfs": "{made: [path], skipped: why}"+   },+   "hint": "Take one before a risky edit (a rename, a big re-route). Libraries in sub-folders are referenced, not copied.",+   "pitfalls": [+    "A snapshot of an open project holds what is saved on disk, not unsaved edits: save first."+   ],+   "related": [+    "project_rename",+    "export_pdf",+    "save"+   ],+   "example": {+    "project": "C:/proj/Board.PrjPcb",+    "label": "before-routing"+   },+   "longRunning": true,+   "timeoutSeconds": 300,+   "proposedBy": "kicad-lane",+   "since": "0.3.0",+   "agreedBy": [+    "altium-lane"+   ]+  },   {    "name": "remove_pours",    "tier": "native",@@ -3860,6 +4791,99 @@    "longRunning": false,    "timeoutSeconds": 300   },+  {+   "name": "render_board_3d",+   "tier": "native",+   "source": "proposed",+   "summary": "Render a 3D picture of the board from one side to an image file, through the tool's own renderer, without opening a window.",+   "input": {+    "filePath": "path to the board file (default: the board open in the tool)",+    "side": "top|bottom|left|right|front|back, default top",+    "width": "int px, default 1600",+    "height": "int px, default 900",+    "quality": "basic|high, default basic (high raytraces and is much slower)",+    "background": "default|transparent|opaque",+    "zoom": "number, default 1.0",+    "perspective": "bool, default false",+    "format": "png|jpg, default png",+    "outputDir": "folder for the output (default beside the board)"+   },+   "output": {+    "image": "path",+    "width": "int",+    "height": "int",+    "side": "string"+   },+   "hint": "One call per side: top and bottom for a review. A flat image of chosen layers is render_board_layers; show_3d_board opens a window instead.",+   "pitfalls": [+    "Parts without a 3D model render as bare pads: check them with bodies first."+   ],+   "related": [+    "render_board_layers",+    "render_schematic",+    "bodies",+    "show_3d_board"+   ],+   "example": {+    "filePath": "C:/proj/Board.PcbDoc",+    "side": "top"+   },+   "longRunning": true,+   "timeoutSeconds": 600,+   "proposedBy": "kicad-lane",+   "since": "0.3.0",+   "agreedBy": [+    "altium-lane"+   ]+  },+  {+   "name": "render_board_layers",+   "tier": "native",+   "source": "proposed",+   "summary": "Render chosen board layers to an image file without opening a window: a preset view (copper, silkscreen, solder mask, paste, outline, drill, assembly or fabrication, of either side) or a list of layers, as png or svg.",+   "input": {+    "preset": "all | top_copper | bottom_copper | top_silkscreen | bottom_silkscreen | top_soldermask | bottom_soldermask | top_paste | bottom_paste | outline | drill | assembly_top | assembly_bottom | fabrication (default all)",+    "layers": "[layer]: copper by its standard name (F.Cu, In1.Cu, B.Cu) or any layer by the tool's own id; overrides preset",+    "format": "png | svg (default png)",+    "dpi": "int, default 300 (png)",+    "mirror": "bool, default false: draw the board as seen from below",+    "monochrome": "bool, default false",+    "outputPath": "the image file to write (default beside the board)",+    "listPresets": "bool: answer the presets and their layers, and make no image"+   },+   "output": {+    "path": "path",+    "format": "png | svg",+    "widthPx": "int (png)",+    "heightPx": "int (png)",+    "preset": "string, or custom when layers was given",+    "layers": "[layer]: what was drawn",+    "presets": "{name: description} (listPresets)"+   },+   "hint": "Each preset is a fixed set of layers, so two bridges draw the same view. For a 3D picture use render_board_3d. The show_* verbs open a window; this one does not.",+   "pitfalls": [+    "Mirroring is never automatic: a bottom preset is drawn as seen from the top unless mirror is true.",+    "Inner copper layers appear only when listed in layers."+   ],+   "related": [+    "render_board_3d",+    "render_schematic",+    "export_gerber",+    "export_pdf"+   ],+   "example": {+    "preset": "assembly_top",+    "format": "png",+    "dpi": 300+   },+   "longRunning": false,+   "timeoutSeconds": 60,+   "proposedBy": "fusion-lane",+   "since": "0.3.0",+   "agreedBy": [+    "altium-lane"+   ]+  },   {    "name": "render_schematic",    "tier": "native",@@ -4715,6 +5739,50 @@    "longRunning": false,    "timeoutSeconds": 900   },+  {+   "name": "check_clearance",+   "tier": "checks",+   "source": "proposed",+   "summary": "Measure the gaps between parts, courtyard to courtyard or pad copper to pad copper, for the listed parts or the whole board, and report every pair under a threshold, closest first.",+   "input": {+    "filePath": "path to the board file (default: the board open in the tool)",+    "refs": "[\"U1\", \"C3\"]: keep pairs that involve one of these (default every part)",+    "mode": "courtyard|pads, default courtyard",+    "thresholdMm": "number, default 0.25 (courtyard) or 0.2 (pads)",+    "includeSameNet": "bool, default false (pads)",+    "maxPairs": "int, default 200"+   },+   "output": {+    "pairs": "[{a, b, distanceMm, overlapping: bool, touching: bool}]",+    "clean": "bool",+    "thresholdMm": "number",+    "measuredOn": "courtyard outline|courtyard box|pads"+   },+   "hint": "Computed from the board model: courtyards compare only parts on the same side, pads only copper that shares a side.",+   "pitfalls": [+    "Rounded pads may be measured as their full rectangle, so a gap can read a little small: the tool's DRC (run_drc) is the authority."+   ],+   "related": [+    "placement_check",+    "run_drc",+    "align_parts"+   ],+   "example": {+    "filePath": "C:/proj/Board.PcbDoc",+    "refs": [+     "U1"+    ],+    "mode": "pads",+    "thresholdMm": 0.2+   },+   "longRunning": false,+   "timeoutSeconds": 60,+   "proposedBy": "kicad-lane",+   "since": "0.3.0",+   "agreedBy": [+    "altium-lane"+   ]+  },   {    "name": "check_orientation",    "tier": "checks",@@ -4853,6 +5921,47 @@    "longRunning": false,    "timeoutSeconds": 120   },+  {+   "name": "estimate_cost",+   "tier": "checks",+   "source": "proposed",+   "summary": "The board's numbers a fab quote needs (size, layers, thickness, smallest track, gap and drill, holes, SMD and through-hole parts and joints, unique parts) and a rough price table at the quantities asked, with every assumption stated and the price source named with the date it was read.",+   "input": {+    "filePath": "path to the board file (default: the board open in the tool)",+    "quantities": "[5, 10, 30, 100] (default)",+    "assembly": "bool, default false: add an assembly estimate",+    "fab": "the price list to use, default jlcpcb"+   },+   "output": {+    "board": "{sizeMm, layers, thicknessMm, minTrackMm, minGapMm, minDrillMm, holes, smdParts, thtParts, smdJoints, thtJoints, uniqueParts}",+    "prices": "[{quantity, board, assembly, total, currency}]",+    "assumptions": "[string]",+    "source": "{name, url, read: date}"+   },+   "hint": "An order of magnitude, not a quote: parts, shipping and options are left out. For a real quote send the manufacturing files to the fab.",+   "pitfalls": [+    "Prices change: source names the price list and the date it was read; an old date means an old price."+   ],+   "related": [+    "fab_check",+    "export_manufacturing",+    "bom"+   ],+   "example": {+    "filePath": "C:/proj/Board.PcbDoc",+    "quantities": [+     5,+     50+    ]+   },+   "longRunning": false,+   "timeoutSeconds": 60,+   "proposedBy": "kicad-lane",+   "since": "0.3.0",+   "agreedBy": [+    "altium-lane"+   ]+  },   {    "name": "fab_check",    "tier": "checks",@@ -5285,6 +6394,48 @@    "longRunning": false,    "timeoutSeconds": 200   },+  {+   "name": "place_decoupling",+   "tier": "checks",+   "source": "proposed",+   "summary": "Plan positions for decoupling capacitors beside an IC's power pins (each cap just outside the courtyard, its power pad facing the pin), answered as move_parts arguments; dryRun:false applies them through move_parts.",+   "input": {+    "filePath": "path to the board file (default: the board open in the tool)",+    "ic": "\"U1\" (required)",+    "caps": "[\"C1\", \"C2\"] (default every capacitor across ground and one of the IC's power nets)",+    "gapMm": "number, default 0.3",+    "dryRun": "bool, default TRUE",+    "expectedRevision": "string: the revision you last read (routing_state); refused with stale_board if the board changed (to apply)"+   },+   "output": {+    "placements": "[{cap, pin, side, x, y, rotation, padToPinMm}]",+    "skipped": "[{cap, why: other_side|no_shared_power_net|no_free_spot}]",+    "moveArgs": "move_parts arguments",+    "validation": "move_parts' courtyard and outline check of the plan",+    "revision": "string, when applied"+   },+   "hint": "Read the plan, then apply it with dryRun:false and expectedRevision, or send moveArgs to move_parts yourself.",+   "pitfalls": [+    "Caps on the other side of the board are skipped: move them to the IC's side first (move_parts with side).",+    "It places; it does not route: route the stubs with route_net."+   ],+   "related": [+    "move_parts",+    "route_net",+    "placement_check"+   ],+   "example": {+    "filePath": "C:/proj/Board.PcbDoc",+    "ic": "U1"+   },+   "longRunning": true,+   "timeoutSeconds": 130,+   "proposedBy": "kicad-lane",+   "since": "0.3.0",+   "agreedBy": [+    "altium-lane"+   ]+  },   {    "name": "placement_check",    "tier": "checks",@@ -5319,6 +6470,108 @@    "longRunning": false,    "timeoutSeconds": 180   },+  {+   "name": "plan_fanout",+   "tier": "checks",+   "source": "proposed",+   "summary": "Plan the fanout of a BGA or QFN/QFP: the pad pitch, dogbone or via-in-pad per pad, the escape layer, surface stubs for the outer ring and a via grid for an exposed pad, answered as route_net arguments, one call per net.",+   "input": {+    "filePath": "path to the board file (default: the board open in the tool)",+    "ref": "\"U3\" (required)",+    "style": "auto|dogbone|via-in-pad, default auto",+    "escapeLayer": "a layer name (default the first inner layer, else the opposite side)",+    "viaMm": "via diameter",+    "viaDrillMm": "via drill",+    "widthMm": "track width",+    "clearanceMm": "number, default 0.1",+    "pitchMm": "override the detected pitch",+    "stubMm": "number, default 0.4",+    "surfaceOuterRing": "bool, default true"+   },+   "output": {+    "package": "bga|perimeter",+    "pitchMm": "number",+    "style": "string",+    "pads": "[{pad, net, action: surface|dogbone|via-in-pad|stub+via|thermal-via-grid|skip}]",+    "calls": "[route_net arguments]",+    "minViaToPadMm": "number"+   },+   "hint": "auto picks dogbone when a via fits between four pads with the clearance, else via-in-pad. Send each call to route_net with filePath and expectedRevision, dry run first.",+   "pitfalls": [+    "Via-in-pad needs filled and capped vias (IPC-4761 type VII): tell the user before committing it.",+    "The plan does not check stubs against other parts' copper; route_net checks each call before it commits."+   ],+   "related": [+    "route_net",+    "place_vias",+    "fab_check"+   ],+   "example": {+    "filePath": "C:/proj/Board.PcbDoc",+    "ref": "U3"+   },+   "longRunning": false,+   "timeoutSeconds": 60,+   "proposedBy": "kicad-lane",+   "since": "0.3.0",+   "agreedBy": [+    "altium-lane"+   ]+  },+  {+   "name": "plan_route",+   "tier": "checks",+   "source": "proposed",+   "summary": "Plan a path for one net between two pads without changing the board: a grid search around the existing copper that keeps the clearance rules, on the allowed copper layers, with vias where they help. Answered as route_net's arguments.",+   "input": {+    "net": "string (required)",+    "from": "the start pad as Ref.Pad (required)",+    "to": "the end pad as Ref.Pad (required)",+    "widthMm": "track width (default the net's rule width)",+    "layers": "[F.Cu, B.Cu, ...]: the layers it may use (default the outer layers)",+    "allowVias": "bool, default true",+    "viaSizeMm": "default 0.6",+    "viaDrillMm": "default 0.3",+    "gridMm": "search grid, default 0.5",+    "viaCost": "a via costs as much as this many mm of track, default 5",+    "expectedRevision": "the revision the plan is for"+   },+   "output": {+    "found": "bool",+    "routeNet": "{net, layer, width, viaSize, viaDrill, paths}: pass it to route_net unchanged",+    "lengthMm": "number",+    "vias": "int",+    "reason": "string when found is false: no path within the search limits, a pad not on the net",+    "revision": "string: the board the plan was made on"+   },+   "hint": "Read only. Pass routeNet to route_net with expectedRevision set to revision; run_drc after the route is still the proof.",+   "pitfalls": [+    "Between dense pads a finer grid can find a path the default 0.5 mm grid misses, at a cost in time.",+    "The plan holds for the revision it read: route_net refuses it with stale_board once the board changes."+   ],+   "related": [+    "route_net",+    "route_pair",+    "run_drc",+    "routing_state"+   ],+   "example": {+    "net": "SDA",+    "from": "U1.12",+    "to": "J3.4",+    "layers": [+     "F.Cu",+     "B.Cu"+    ]+   },+   "longRunning": false,+   "timeoutSeconds": 30,+   "proposedBy": "fusion-lane",+   "since": "0.3.0",+   "agreedBy": [+    "altium-lane"+   ]+  },   {    "name": "read_sheet_file",    "tier": "checks",@@ -5929,6 +7182,42 @@    "longRunning": false,    "timeoutSeconds": 120   },+  {+   "name": "close_all_documents",+   "tier": "app",+   "source": "proposed",+   "summary": "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 save or discardUnsaved says what to do with it.",+   "input": {+    "save": "bool, default false: save each changed document, then close it",+    "discardUnsaved": "bool, default false: close changed documents without saving (their changes are lost)",+    "includeScratch": "bool, default false: also close never-saved scratch documents"+   },+   "output": {+    "closed": "[name]",+    "saved": "[name]",+    "keptOpen": "[{name, why: unsaved changes | scratch}]"+   },+   "hint": "Use it to start from a clean editor. keptOpen tells you what still needs a decision.",+   "pitfalls": [+    "discardUnsaved loses changes that exist nowhere else: ask the person first.",+    "A scratch document was never saved, so closing one with unsaved changes loses it entirely."+   ],+   "related": [+    "close_document",+    "save",+    "document_info"+   ],+   "example": {+    "save": true+   },+   "longRunning": false,+   "timeoutSeconds": 120,+   "proposedBy": "fusion-lane",+   "since": "0.3.0",+   "agreedBy": [+    "altium-lane"+   ]+  },   {    "name": "close_document",    "tier": "app",@@ -5983,6 +7272,44 @@    "longRunning": false,    "timeoutSeconds": 60   },+  {+   "name": "cross_probe",+   "tier": "app",+   "source": "proposed",+   "summary": "From a schematic part to the board part linked to it, and back, by designator, the schematic symbol's id or its sheet path; optionally select them in the tool.",+   "input": {+    "filePath": "path to the board file (default: the board open in the tool)",+    "ref": "\"U1\"",+    "symbolId": "the schematic symbol's id",+    "path": "the symbol's sheet path",+    "schematic": "path to a sheet of the project (default the project's)",+    "select": "bool, default false: also select the matches in the tool"+   },+   "output": {+    "matches": "[{board: {ref, id, side, x, y, rotation}, schematic: {sheet, id, ref, symbol, value}, linked: bool}]",+    "symbolWithoutPart": "[ref]"+   },+   "hint": "Reads the open board when the tool serves it, else the file.",+   "pitfalls": [+    "linked:false means the board part has no link to a symbol: placed by hand, or update_pcb never ran."+   ],+   "related": [+    "selection",+    "update_pcb",+    "component_data"+   ],+   "example": {+    "filePath": "C:/proj/Board.PcbDoc",+    "ref": "U3"+   },+   "longRunning": false,+   "timeoutSeconds": 60,+   "proposedBy": "kicad-lane",+   "since": "0.3.0",+   "agreedBy": [+    "altium-lane"+   ]+  },   {    "name": "demo",    "tier": "app",@@ -6120,6 +7447,40 @@    "longRunning": false,    "timeoutSeconds": 30   },+  {+   "name": "document_info",+   "tier": "app",+   "source": "proposed",+   "summary": "The active document: its name, what kind it is, whether it has unsaved changes, where it is saved and which version it is. Read only; opens nothing.",+   "input": {},+   "output": {+    "name": "string",+    "kind": "project | schematic | board | library | model | other",+    "saved": "bool: it exists as a file or a cloud item",+    "modified": "bool: it has unsaved changes",+    "path": "file path or cloud location | null",+    "version": "int | null: the saved version, where the tool keeps versions",+    "project": "string | null"+   },+   "hint": "Cheap. Call it before an edit verb to make sure the right document is in front.",+   "pitfalls": [+    "A schematic and a board of one design are separate documents in some tools: kind says which one is in front."+   ],+   "related": [+    "open_document",+    "close_document",+    "save",+    "status"+   ],+   "example": {},+   "longRunning": false,+   "timeoutSeconds": 20,+   "proposedBy": "fusion-lane",+   "since": "0.3.0",+   "agreedBy": [+    "altium-lane"+   ]+  },   {    "name": "ensure_licensed",    "tier": "app",@@ -6374,6 +7735,50 @@    "longRunning": false,    "timeoutSeconds": 240   },+  {+   "name": "library_views",+   "tier": "app",+   "source": "proposed",+   "summary": "Pictures of library parts for review, each as an image file: the schematic symbol, the footprint (pads and layers), the 3D body seated on the footprint, and the device view that maps symbol pins to pads.",+   "input": {+    "libraryPath": "path to the library (required)",+    "parts": "[part name] (required)",+    "views": "[symbol, footprint, 3d, device] (default all four)",+    "outputDir": "folder for the images (default beside the library)"+   },+   "output": {+    "captured": "[{part, view, path, ok, error?}]"+   },+   "hint": "The four pictures a reviewer checks before a part is used: the pin names on the symbol, the pad shapes, the body on its pads, and every pin mapped to a pad.",+   "pitfalls": [+    "The 3d view needs a body on the part (add_body): a part without one is reported with ok false, not drawn empty."+   ],+   "related": [+    "add_body",+    "show_3d_chip",+    "read_symbol",+    "footprint_primitives",+    "list_library"+   ],+   "example": {+    "libraryPath": "C:/libs/power.lbr",+    "parts": [+     "TPS54202"+    ],+    "views": [+     "symbol",+     "footprint",+     "3d"+    ]+   },+   "longRunning": true,+   "timeoutSeconds": 300,+   "proposedBy": "fusion-lane",+   "since": "0.3.0",+   "agreedBy": [+    "altium-lane"+   ]+  },   {    "name": "license",    "tier": "app",