KiCad - the KiCad Bridge
Public Made by Adomby adom
Drive your own KiCad from an AI, in the background: open every editor, read the whole board as data (the EDA Bridge Standard board model), stack-up, part heights, netlists, place, route, pour, DRC and exports.
master
e14cd83
13d ago
name: kicad-board-checks description: >- Check a KiCad board the way the EDA Bridge Standard checks every board, and fix what the checks find: return paths over gaps in the reference copper, copper balance (bow and twist), impedance track widths from the stack-up, current capacity (IPC-2221), net lengths and differential-pair skew, matched-length groups, 3D heights and enclosure fit, a placement review (overlaps, parts off the board, on a mounting hole), part orientation, free space for a part, symbols against footprints, net classes from net names, thermal vias in an exposed pad, a via fence for EMC, reference designators placed clear of the pads, the BOM (one line per MPN, JLCPCB, Mouser and DigiKey files), JLCPCB assembly tiers, a JLCPCB order in one call, and one HTML board report with a picture. Works from the .kicad_pcb file without KiCad running, or live from the PCB editor. Trigger words: board review, check my board, design review, return path, ground plane gap, split plane, copper balance, board warp, bow and twist, impedance, 50 ohm trace width, 90 ohm USB pair, trace width for current, how many amps, can jlcpcb make it, fab limits, fab check, design rules check against a fab, IPC-2221, net length, length matching, pair skew, DDR length, height check, will it fit the enclosure, placement check, parts overlapping, part off the board, part too tall, 3D collision, rotate parts, find space, where can this part go, pin pad mismatch, symbol footprint mismatch, net classes, auto classes, power class, thermal vias, exposed pad vias, via stitching, via fence, EMC fence, RF fence, board report, report html, bom, bill of materials, jlcpcb bom, cpl, pick and place, lcsc numbers, missing mpn, jlcpcb assembly, economic or standard assembly, order from jlcpcb, gerber zip, order the board, designators, silkscreen labels, reference designators on pads, label placement, panelize, mouse bites, tabs, v-score, panel, build a board, test board, read schematic file, length tune, length matching, serpentine, meander, match length, skew, silkscreen prep, silk on pads, component class, room, keep parts together, library views, picture of a part, generate a 3D body, make a STEP model, plan a route, path between two pads, symbol and footprint images, review a library part, pin to pad map, hide a layer, layer visibility.
Board checks
Sixteen verbs check a board and, where a fix is mechanical, apply it. They answer the EDA Bridge
Standard's checks tier (adom/eda-bridge-standard), the same questions altium_* and fusion_* answer, so
an AI that reviews one tool's board reviews them all.
Every check reads the live PCB editor when it serves the board (unsaved edits included) and the file
otherwise; source:"file" forces the file. Coordinates are mm with y up (the standard's frame) unless
frame:"kicad". A reply's revision is the standard revision: pass it as expectedRevision to the edit
verbs.
Computed by the shared engine (adom-eda-checks)
The standard's own checks engine, vendored unchanged in rust/vendor/adom-eda-checks, computes these from
the board model, kicad_layer_stack, kicad_pour_state and kicad_bodies. Every reply names it in
engine ("adom-eda-checks 0.4.0"):
| Verb | Answers | Fix it with |
|---|---|---|
kicad_return_path |
signal tracks over no pour or plane on either neighbouring layer: nets[] {net, layer, unreferencedMm, firstGapAt} |
fix is a ready kicad_apply_zone_plan call that pours the reference net under each gap; refill, then check again |
kicad_copper_balance |
copper per layer (pours included) and mirrored pairs within 20 points | pour the lighter layer |
kicad_impedance {z0, diff?, gapMm?} |
per copper layer the width (and pair width and gap) for the target, microstrip or stripline from the stack-up | apply:{scope:"A.NetClass == 'USB'"} adds a ready kicad_custom_rules call (track_width, diff_pair_gap per layer at +/-10%) |
kicad_fab_check {fab:"jlcpcb"} |
the board's smallest features against the fab's record from adom/pcb-design-rules (fab.source and fab.read say which page and when), or your limits: fits, outsideLimits {limit, limitMm, boardMm, at} |
a footprint change, a wider track, or the fab's advanced service |
kicad_current_capacity {nets:{VIN:3}} |
per net and layer the narrowest track against the IPC-2221 width, and vias per layer change | kicad_set_track_width, a width rule, or a pour |
kicad_height_check {maxTopMm, regions} |
heights from the 3D models (kicad_bodies), parts over a limit or under a lid feature, bodies that collide or come closer than minGapMm; complete is false while noBody lists parts without a model |
a lower part, or a body for each noBody part |
kicad_plan_route {net, from: "U1.3", to: "J2.1", layers?, gridMm?} |
a path for one net between two pads, around the copper and inside the clearance rules, vias where they help; nothing changes | routeNet is kicad_route_net's own arguments (filePath, frame, expectedRevision included): pass it unchanged, then kicad_run_drc. Fine-pitch pads need gridMm: 0.1; pours are not obstacles, so refill after |
kicad_placement_check {marginMm?, edgeMm?} |
before routing: parts whose pads and bodies overlap on one side, parts off or over the edge, pads near the edge, parts on a mounting hole (bodiesUsed says the bodies were read) |
kicad_find_space, kicad_move_footprint |
A board saved without a stack-up uses KiCad's defaults (35 um copper, FR4 Dk 4.5) and says so in
assumed: set Board Setup > Physical Stackup before trusting impedance.
Computed by the bridge
| Verb | Answers |
|---|---|
kicad_net_lengths |
routed length per net by layer, pair skew (pairs KiCad recognises by name, or pairs), matched-length groups with shortByMm |
kicad_check_orientation |
two-pad parts whose airline is shorter turned 90/180/270 (advisory, nothing moved) |
kicad_find_space {part, near} |
free spots for a part near another, clear of courtyards, that side's copper and the edge; check:true lists overlaps and parts off the board |
kicad_pin_pad_check |
symbol pins (the schematic's netlist) against footprint pads, part by part |
kicad_auto_classes |
GND, Power, Clock and HighSpeed from net names, and the pairs; apply:true writes them with kicad_netclasses |
Edits: vias
kicad_thermal_vias {ref, pad?} fills a part's exposed pad (its largest pad by default) with a centred,
inset grid on the pad's net. kicad_via_fence {viaNet, nets?, edge?, freqGHz?} lines both sides of fast
tracks and/or the board edge with ground vias at lambda/20 (FR-4) or pitchMm, each clear of other copper,
pads, vias, via keepouts and the edge.
The engine plans both (dryRun:true returns planned.points, and planned.via.from says where the via
size came from), then the bridge places the vias:
- live when the PCB editor serves the board: one Undo step, after KiCad's DRC (pours refilled) proves
the vias add no error (
drc_rejectedotherwise, nothing changed); - in the closed file otherwise, after the same DRC check, with a
.adom-bakbackup.
Size and drill default to the project's Default net class via; the fence's clearance to the board's
largest clearance rule. Afterwards refill the pours
(kicad_zone_state {refill:true}) so they join the vias: until then a file DRC shows the old fill
overlapping them, and thermal vias read as dangling until the far side has copper of their net.
Designators
kicad_silk_designators {size: 1.0} places every reference designator upright beside its own part (above,
below, right, left, slid along a side, a corner, last on its own body), clear of every pad by padClearance
(JLCPCB: 0.15 mm), of other parts' bodies and of the other labels, inside the board; bigger parts choose first.
Parts with no clear spot are listed in unplaced, never forced onto pads: allow a smaller minSize. The labels
move in the open PCB editor through kicad_silk_fields_batch (one Undo step after a DRC check) and are read
back: onPadsAfter must be empty. On a closed board the reply is the plan.
kicad_silkscreen_prep readies the silkscreen for fab on a closed board:
- it sets the Gerbers to subtract the solder mask from the silkscreen (KiCad's own clipping);
- it deletes silkscreen lying outside the board;
- it moves designators that sit on pads, using
kicad_silk_designators; - it counts KiCad's silk DRC findings before and after.
Component classes
kicad_component_classes {name, members, room?} puts parts in a class (KiCad 9+: each member footprint carries the
class, and rules match it with A.hasComponentClass('<name>')). room: true (or {marginMm}, or {rect}) adds a rule
area Adom room <name> round them and a rule in the project's .kicad_dru that flags any member outside it
(assertion_failure). Without name it lists the classes and rooms; remove: true takes a class, its room and its
rule away. Edits need the board closed.
Ordering from JLCPCB
| Verb | Answers |
|---|---|
kicad_bom {projectPath, boards?} |
the schematic's parts (fields, DNP, exclude from BOM) merged with the board, one line per MPN; checks say what an order lacks; writes bom.csv, bom-jlcpcb.csv + cpl-jlcpcb.csv, bom-mouser.csv, bom-digikey.csv and bom.json into <project>/BOM |
kicad_assembly_check {projectPath, panelMm?} |
the board against JLCPCB's Economic and Standard assembly tiers (size, thickness, layers, sides, smallest package, finest pitch, fiducials, LCSC numbers): service is the cheapest tier every rule allows |
kicad_jlcpcb_order {projectPath} |
fab_check, the Gerbers and drill zipped, the BOM and CPL, the tiers and the order-form values (layers, size, thickness, copper, smallest track/space and hole) in one folder, issues from every step, ready |
Field names are matched across libraries: MPN = Manufacturer Part Number; LCSC = LCSC Part # = JLCPCB Part #; Mouser Part #; DigiKey Part #. Parts with an MPN or manufacturer of "none" (test pads, logos) stay in the BOM and out of the ordering files. Parts excluded from the BOM or the position files, DNP and board-only ones are not counted as placed parts. CPL positions are KiCad's position-file numbers (mm, y up): check every part's rotation in JLCPCB's preview.
Length tuning
kicad_length_tune {net, targetMm | matchTo} adds the missing length as a serpentine of square bumps in the
net's longest straight track that has room on one side (each bump adds twice its amplitude, at most
maxAmplitudeMm), clear of other copper, pads, vias and the edge. It swaps the track live as one Undo step,
or in the closed file, only after KiCad's DRC finds no new error. kicad_net_lengths {groups} says which nets
of a matched group are short and by how much.
Panels and new boards
kicad_panelize {pcbPath, rows, cols, separation} steps a rectangular board into a panel: vscore (copies
abutting, V-cut lines on Cmts.User) or tabs (copies gapMm apart, 2 mm by default, the rout path on Edge.Cuts
broken at mouse-bite tabs with five 0.6 mm holes each, rails all round). jlcpcb.rules checks JLCPCB's panel
rules for either. kicad_build_board {pcbPath, outline, parts, nets} makes a new board from a parts list and a
netlist (footprints by Library:Name or from a .pretty libraryPath), read back pin by pin; kicad_test_board
lays one footprint or a ; list on a new or existing board to look at. kicad_read_sheet_file reads a
schematic sheet's parts, fields and pins straight from the file.
Library parts, pictured
kicad_library_views {libraryPath, parts} draws each part the way a reviewer checks it before it is used,
headless through kicad-cli, nothing opened: the symbol (<part>-symbol.png, one per unit), the footprint with
its pad numbers (-footprint.png), the 3D body seated on its pads (-3d.png, an isometric render of a
one-part board, zoomed out for a tall body) and the device view (-device.svg, every symbol pin against a pad:
pinsWithoutPad and padsWithoutPin should both be empty). From a .kicad_sym the footprint is the symbol's
Footprint field; from a .pretty folder pass symbolLibraryPath for the symbol. A footprint without a model,
or whose model file does not resolve, gets ok:false for 3d, never an empty picture.
kicad_generate_body {family, dimensionsMm?, marking?, libraryPath?, footprintName?} makes a part's 3D body
from its package family (chip, SOIC, QFN, QFP, BGA, SOT-23, DFN, MELF, can, crystal, header) and the datasheet's
JEDEC letters, to IPC-7351 proportions, with an optional marking on top. The standard's engine writes the STEP;
with libraryPath it lands in <Lib>.3dshapes, and footprintName attaches it (kicad_add_body). Compare
bboxMm with the datasheet before trusting it, then look with kicad_library_views {views:["3d"]}.
kicad_set_layer_visibility {layer | layerId, displayed} shows or hides one layer in the open PCB editor and
reads it back. It is view state the user keeps seeing: restore what you hid.
The report
kicad_board_report {projectPath} runs DRC, ERC, the board against the schematic, symbols against
footprints, the fab's limits (fab, default jlcpcb), return paths, copper balance, impedance widths, 3D
heights, lengths and orientation, renders the top side, and writes one self-contained HTML file beside the
project. sections[] say pass, needs work, or information, and name the verb that gives each in full. A
check that could not run is reported as not run, never as a pass.
Pitfalls
- Pours count as KiCad last filled them: after editing copper, refill before trusting return_path or copper_balance on a file read.
kicad_height_checkuses each model's bounding box: round parts can be reported colliding at corners.kicad_pin_pad_checkexpects mounting, shield, exposed and thermal pads (MH*, MP*, SH*, EP*, PAD*, TAB*, unnamed or 0) to have no pin.kicad_auto_classesreads names only: a clock on a net called SIG7 is not found.
---
name: kicad-board-checks
description: >-
Check a KiCad board the way the EDA Bridge Standard checks every board, and fix what the checks find: return paths over gaps in the reference copper, copper balance (bow and twist), impedance track widths from the stack-up, current capacity (IPC-2221), net lengths and differential-pair skew, matched-length groups, 3D heights and enclosure fit, a placement review (overlaps, parts off the board, on a mounting hole), part orientation, free space for a part, symbols against footprints, net classes from net names, thermal vias in an exposed pad, a via fence for EMC, reference designators placed clear of the pads, the BOM (one line per MPN, JLCPCB, Mouser and DigiKey files), JLCPCB assembly tiers, a JLCPCB order in one call, and one HTML board report with a picture. Works from the .kicad_pcb file without KiCad running, or live from the PCB editor. Trigger words: board review, check my board, design review, return path, ground plane gap, split plane, copper balance, board warp, bow and twist, impedance, 50 ohm trace width, 90 ohm USB pair, trace width for current, how many amps, can jlcpcb make it, fab limits, fab check, design rules check against a fab, IPC-2221, net length, length matching, pair skew, DDR length, height check, will it fit the enclosure, placement check, parts overlapping, part off the board, part too tall, 3D collision, rotate parts, find space, where can this part go, pin pad mismatch, symbol footprint mismatch, net classes, auto classes, power class, thermal vias, exposed pad vias, via stitching, via fence, EMC fence, RF fence, board report, report html, bom, bill of materials, jlcpcb bom, cpl, pick and place, lcsc numbers, missing mpn, jlcpcb assembly, economic or standard assembly, order from jlcpcb, gerber zip, order the board, designators, silkscreen labels, reference designators on pads, label placement, panelize, mouse bites, tabs, v-score, panel, build a board, test board, read schematic file, length tune, length matching, serpentine, meander, match length, skew, silkscreen prep, silk on pads, component class, room, keep parts together, library views, picture of a part, generate a 3D body, make a STEP model, plan a route, path between two pads, symbol and footprint images, review a library part, pin to pad map, hide a layer, layer visibility.
---
# Board checks
Sixteen verbs check a board and, where a fix is mechanical, apply it. They answer the EDA Bridge
Standard's checks tier (adom/eda-bridge-standard), the same questions `altium_*` and `fusion_*` answer, so
an AI that reviews one tool's board reviews them all.
Every check reads the live PCB editor when it serves the board (unsaved edits included) and the file
otherwise; `source:"file"` forces the file. Coordinates are mm with y up (the standard's frame) unless
`frame:"kicad"`. A reply's `revision` is the standard revision: pass it as `expectedRevision` to the edit
verbs.
## Computed by the shared engine (adom-eda-checks)
The standard's own checks engine, vendored unchanged in `rust/vendor/adom-eda-checks`, computes these from
the board model, `kicad_layer_stack`, `kicad_pour_state` and `kicad_bodies`. Every reply names it in
`engine` ("adom-eda-checks 0.4.0"):
| Verb | Answers | Fix it with |
|---|---|---|
| `kicad_return_path` | signal tracks over no pour or plane on either neighbouring layer: `nets[] {net, layer, unreferencedMm, firstGapAt}` | `fix` is a ready `kicad_apply_zone_plan` call that pours the reference net under each gap; refill, then check again |
| `kicad_copper_balance` | copper per layer (pours included) and mirrored pairs within 20 points | pour the lighter layer |
| `kicad_impedance {z0, diff?, gapMm?}` | per copper layer the width (and pair width and gap) for the target, microstrip or stripline from the stack-up | `apply:{scope:"A.NetClass == 'USB'"}` adds a ready `kicad_custom_rules` call (track_width, diff_pair_gap per layer at +/-10%) |
| `kicad_fab_check {fab:"jlcpcb"}` | the board's smallest features against the fab's record from adom/pcb-design-rules (`fab.source` and `fab.read` say which page and when), or your `limits`: `fits`, `outsideLimits {limit, limitMm, boardMm, at}` | a footprint change, a wider track, or the fab's advanced service |
| `kicad_current_capacity {nets:{VIN:3}}` | per net and layer the narrowest track against the IPC-2221 width, and vias per layer change | `kicad_set_track_width`, a width rule, or a pour |
| `kicad_height_check {maxTopMm, regions}` | heights from the 3D models (`kicad_bodies`), parts over a limit or under a lid feature, bodies that collide or come closer than `minGapMm`; `complete` is false while `noBody` lists parts without a model | a lower part, or a body for each `noBody` part |
| `kicad_plan_route {net, from: "U1.3", to: "J2.1", layers?, gridMm?}` | a path for one net between two pads, around the copper and inside the clearance rules, vias where they help; nothing changes | `routeNet` is `kicad_route_net`'s own arguments (filePath, frame, expectedRevision included): pass it unchanged, then `kicad_run_drc`. Fine-pitch pads need `gridMm: 0.1`; pours are not obstacles, so refill after |
| `kicad_placement_check {marginMm?, edgeMm?}` | before routing: parts whose pads and bodies overlap on one side, parts off or over the edge, pads near the edge, parts on a mounting hole (`bodiesUsed` says the bodies were read) | `kicad_find_space`, `kicad_move_footprint` |
A board saved without a stack-up uses KiCad's defaults (35 um copper, FR4 Dk 4.5) and says so in
`assumed`: set Board Setup > Physical Stackup before trusting impedance.
## Computed by the bridge
| Verb | Answers |
|---|---|
| `kicad_net_lengths` | routed length per net by layer, pair skew (pairs KiCad recognises by name, or `pairs`), matched-length `groups` with `shortByMm` |
| `kicad_check_orientation` | two-pad parts whose airline is shorter turned 90/180/270 (advisory, nothing moved) |
| `kicad_find_space {part, near}` | free spots for a part near another, clear of courtyards, that side's copper and the edge; `check:true` lists overlaps and parts off the board |
| `kicad_pin_pad_check` | symbol pins (the schematic's netlist) against footprint pads, part by part |
| `kicad_auto_classes` | GND, Power, Clock and HighSpeed from net names, and the pairs; `apply:true` writes them with `kicad_netclasses` |
## Edits: vias
`kicad_thermal_vias {ref, pad?}` fills a part's exposed pad (its largest pad by default) with a centred,
inset grid on the pad's net. `kicad_via_fence {viaNet, nets?, edge?, freqGHz?}` lines both sides of fast
tracks and/or the board edge with ground vias at lambda/20 (FR-4) or `pitchMm`, each clear of other copper,
pads, vias, via keepouts and the edge.
The engine plans both (`dryRun:true` returns `planned.points`, and `planned.via.from` says where the via
size came from), then the bridge places the vias:
- **live** when the PCB editor serves the board: one Undo step, after KiCad's DRC (pours refilled) proves
the vias add no error (`drc_rejected` otherwise, nothing changed);
- **in the closed file** otherwise, after the same DRC check, with a `.adom-bak` backup.
Size and drill default to the project's Default net class via; the fence's clearance to the board's
largest clearance rule. Afterwards refill the pours
(`kicad_zone_state {refill:true}`) so they join the vias: until then a file DRC shows the old fill
overlapping them, and thermal vias read as dangling until the far side has copper of their net.
## Designators
`kicad_silk_designators {size: 1.0}` places every reference designator upright beside its own part (above,
below, right, left, slid along a side, a corner, last on its own body), clear of every pad by `padClearance`
(JLCPCB: 0.15 mm), of other parts' bodies and of the other labels, inside the board; bigger parts choose first.
Parts with no clear spot are listed in `unplaced`, never forced onto pads: allow a smaller `minSize`. The labels
move in the open PCB editor through `kicad_silk_fields_batch` (one Undo step after a DRC check) and are read
back: `onPadsAfter` must be empty. On a closed board the reply is the plan.
`kicad_silkscreen_prep` readies the silkscreen for fab on a closed board:
- it sets the Gerbers to subtract the solder mask from the silkscreen (KiCad's own clipping);
- it deletes silkscreen lying outside the board;
- it moves designators that sit on pads, using `kicad_silk_designators`;
- it counts KiCad's silk DRC findings before and after.
## Component classes
`kicad_component_classes {name, members, room?}` puts parts in a class (KiCad 9+: each member footprint carries the
class, and rules match it with `A.hasComponentClass('<name>')`). `room: true` (or `{marginMm}`, or `{rect}`) adds a rule
area `Adom room <name>` round them and a rule in the project's .kicad_dru that flags any member outside it
(`assertion_failure`). Without `name` it lists the classes and rooms; `remove: true` takes a class, its room and its
rule away. Edits need the board closed.
## Ordering from JLCPCB
| Verb | Answers |
|---|---|
| `kicad_bom {projectPath, boards?}` | the schematic's parts (fields, DNP, exclude from BOM) merged with the board, one line per MPN; `checks` say what an order lacks; writes bom.csv, bom-jlcpcb.csv + cpl-jlcpcb.csv, bom-mouser.csv, bom-digikey.csv and bom.json into `<project>/BOM` |
| `kicad_assembly_check {projectPath, panelMm?}` | the board against JLCPCB's Economic and Standard assembly tiers (size, thickness, layers, sides, smallest package, finest pitch, fiducials, LCSC numbers): `service` is the cheapest tier every rule allows |
| `kicad_jlcpcb_order {projectPath}` | fab_check, the Gerbers and drill zipped, the BOM and CPL, the tiers and the order-form values (layers, size, thickness, copper, smallest track/space and hole) in one folder, `issues` from every step, `ready` |
Field names are matched across libraries: MPN = Manufacturer Part Number; LCSC = LCSC Part # = JLCPCB Part #;
Mouser Part #; DigiKey Part #. Parts with an MPN or manufacturer of "none" (test pads, logos) stay in the BOM
and out of the ordering files. Parts excluded from the BOM or the position files, DNP and board-only ones are
not counted as placed parts. CPL positions are KiCad's position-file numbers (mm, y up): check every part's
rotation in JLCPCB's preview.
## Length tuning
`kicad_length_tune {net, targetMm | matchTo}` adds the missing length as a serpentine of square bumps in the
net's longest straight track that has room on one side (each bump adds twice its amplitude, at most
`maxAmplitudeMm`), clear of other copper, pads, vias and the edge. It swaps the track live as one Undo step,
or in the closed file, only after KiCad's DRC finds no new error. `kicad_net_lengths {groups}` says which nets
of a matched group are short and by how much.
## Panels and new boards
`kicad_panelize {pcbPath, rows, cols, separation}` steps a rectangular board into a panel: `vscore` (copies
abutting, V-cut lines on Cmts.User) or `tabs` (copies `gapMm` apart, 2 mm by default, the rout path on Edge.Cuts
broken at mouse-bite tabs with five 0.6 mm holes each, rails all round). `jlcpcb.rules` checks JLCPCB's panel
rules for either. `kicad_build_board {pcbPath, outline, parts, nets}` makes a new board from a parts list and a
netlist (footprints by Library:Name or from a .pretty `libraryPath`), read back pin by pin; `kicad_test_board`
lays one footprint or a `;` list on a new or existing board to look at. `kicad_read_sheet_file` reads a
schematic sheet's parts, fields and pins straight from the file.
## Library parts, pictured
`kicad_library_views {libraryPath, parts}` draws each part the way a reviewer checks it before it is used,
headless through kicad-cli, nothing opened: the symbol (`<part>-symbol.png`, one per unit), the footprint with
its pad numbers (`-footprint.png`), the 3D body seated on its pads (`-3d.png`, an isometric render of a
one-part board, zoomed out for a tall body) and the device view (`-device.svg`, every symbol pin against a pad:
`pinsWithoutPad` and `padsWithoutPin` should both be empty). From a `.kicad_sym` the footprint is the symbol's
Footprint field; from a `.pretty` folder pass `symbolLibraryPath` for the symbol. A footprint without a model,
or whose model file does not resolve, gets `ok:false` for 3d, never an empty picture.
`kicad_generate_body {family, dimensionsMm?, marking?, libraryPath?, footprintName?}` makes a part's 3D body
from its package family (chip, SOIC, QFN, QFP, BGA, SOT-23, DFN, MELF, can, crystal, header) and the datasheet's
JEDEC letters, to IPC-7351 proportions, with an optional marking on top. The standard's engine writes the STEP;
with `libraryPath` it lands in `<Lib>.3dshapes`, and `footprintName` attaches it (kicad_add_body). Compare
`bboxMm` with the datasheet before trusting it, then look with `kicad_library_views {views:["3d"]}`.
`kicad_set_layer_visibility {layer | layerId, displayed}` shows or hides one layer in the open PCB editor and
reads it back. It is view state the user keeps seeing: restore what you hid.
## The report
`kicad_board_report {projectPath}` runs DRC, ERC, the board against the schematic, symbols against
footprints, the fab's limits (`fab`, default jlcpcb), return paths, copper balance, impedance widths, 3D
heights, lengths and orientation, renders the top side, and writes one self-contained HTML file beside the
project. `sections[]` say pass, needs work, or information, and name the verb that gives each in full. A
check that could not run is reported as not run, never as a pass.
## Pitfalls
- Pours count as KiCad last filled them: after editing copper, refill before trusting return_path or
copper_balance on a file read.
- `kicad_height_check` uses each model's bounding box: round parts can be reported colliding at corners.
- `kicad_pin_pad_check` expects mounting, shield, exposed and thermal pads (MH*, MP*, SH*, EP*, PAD*, TAB*,
unnamed or 0) to have no pin.
- `kicad_auto_classes` reads names only: a clock on a net called SIG7 is not found.