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
kicad-bridge release notes
Newest first. Written at publish time by tools/build_release.py, which refuses to publish without one.
Backfilled below 0.9.273 (2026-09-02). Releases 0.9.261-0.9.272 shipped with
no usable changelog: build_release.py never passed --changelog, so the server
synthesised "- Update N file(s)" from repo-push commits that were themselves
unnamed. These entries were reconstructed after the fact from the work they
contain, which is exactly the situation the mandatory-notes gate now prevents.
Treat them as accurate but secondhand.
1.0.107 (2026-11-08 18:17 UTC)
NATIVE (Rust) build. kicad_move_footprint refuses an argument it does not read (errorCode unknown_argument, nothing moved), so a misspelling such as rot for rotation no longer moves a part without turning it; suggestedKey names the right key (contributed by Josh Aberdeen, PR #70). The call's reason and caller, the bridge's own keys and kicad_align_parts's arguments are still accepted.
1.0.106 (2026-11-08 13:33 UTC)
NATIVE (Rust) build. kicad_silk_text_batch, kicad_silk_fields_batch and kicad_silk_graphics_batch take frame:"standard", so the y-up positions kicad_silk_state reports by default go back unchanged (wiki #141). kicad_silk_text_batch refuses a text placed outside the board outline with errorCode text_off_board, and says when a negative y looks like a y-up position sent without frame:"standard"; allowOffBoard:true lets it through. kicad_silk_state's reply says which frame its positions are in and how to send them back.
1.0.105 (2026-11-06 21:20 UTC)
NATIVE (Rust) build. Live routing and edit verbs (kicad_route_net and the others that compare DRC before and after) no longer refuse with drc_incomplete when only warning types, such as silk_overlap or silk_over_copper on a dense board, reach KiCad's 199-per-type report cap (wiki #140). An error type at its cap still refuses, and the refusal now names it in cappedErrorTypes. violationReportMayBeTruncated is still reported for information.
1.0.104 (2026-11-05 19:07 UTC)
NATIVE (Rust) build. kicad_close_all_documents and kicad_close no longer close a board or schematic another AI thread opened or used (wiki #139). Such a document stays open with keptOpen why "opened by "; kicad_close refuses with errorCode documents_in_use and closes nothing. force:true with a reason closes past it. kicad_close_document {path} closes your own board as before.
1.0.103 (2026-11-05 16:11 UTC)
NATIVE (Rust) build. kicad_pcm_install and kicad_pcm_uninstall refuse a package identifier that is a path (errorCode invalid_identifier). Before this, an identifier holding a full folder path, including one set by a package zip's metadata.json, deleted that folder.
1.0.102 (2026-11-05 01:29 UTC)
NATIVE (Rust) build. 1.0.102: kicad_show_library with only a library name now just shows the library.
- Fix, parts walked: with no part named, kicad_show_library set the filter and then kept trying to load one, clicking through the library's parts row by row and leaving the last one on the canvas. It now stops once the filter is set, for symbols and footprints. Calls that name a part are unchanged.
- Fix, parts listed: the tree now lists every part of the library and nothing from other libraries. The filter was a text search on the name, which left out parts that didn't mention it and could pull in other libraries' parts that did.
- The reply says what the canvas shows: a warm editor keeps the part it already had, so canvasPart names it and canvasFromOtherLibrary says if it came from another library. A proof image shows that part until one is loaded.
- Fix, empty editors: a capture of an editor with no part loaded no longer waits for a canvas that will never paint, and says canvasExpectedEmpty instead of warning that the canvas is blank. That takes about 20 seconds off these calls.
- Behaviour change: if the filter can't be set, the reply is now success:false with library_filter_failed. It used to say success with the library shown.
Tested on KiCad 10.0.8 (battery 3/0/1 pass/fail/skip on DESKTOP-BAR6S0F).
1.0.101 (2026-11-05 01:16 UTC)
NATIVE (Rust) build. 1.0.101: kicad_show_library with only a library name now just shows the library.
- Fix, parts walked: with no part named, kicad_show_library set the filter and then kept trying to load one, clicking through the library's parts row by row and leaving the last one on the canvas. It now stops once the filter is set, for symbols and footprints. Calls that name a part are unchanged.
- Fix, parts listed: the tree now lists every part of the library and nothing from other libraries. The filter was a text search on the name, which left out parts that didn't mention it and could pull in other libraries' parts that did.
- The reply says what the canvas shows: a warm editor keeps the part it already had, so canvasPart names it and canvasFromOtherLibrary says if it came from another library. A proof image shows that part until one is loaded.
- Behaviour change: if the filter can't be set, the reply is now success:false with library_filter_failed. It used to say success with the library shown.
Tested on KiCad 10.0.8 (battery 3/0/1 pass/fail/skip on DESKTOP-BAR6S0F).
1.0.100 (2026-11-02 22:25 UTC)
NATIVE (Rust) build. 1.0.100: kicad_update_pcb sets every new part's reference, whichever way its library wrote it (#138), and the verbs ruled on standard #29.
- #138 fixed: new parts could keep their library's REF** placeholder and read as missing, because the verb only recognised KiCad's own spacing of the reference. It now handles any spacing or line breaks, bare words and the older fp_text form, and adds the field if the footprint has none. The value is set the same way.
- New refusal: a part that still doesn't read back with its reference now stops the update with reference_not_set and names the footprint, instead of being written to the board.
- Boards already updated: a board that already has REF** parts isn't repaired by running the update again. Start from the empty board, or set those references from the matching symbols.
- New verbs:
- kicad_place_parts: footprints from a library onto a board, with position, rotation and side, read back. Each part is its own Undo step.
- kicad_edit_tracks: width, layer and ends of given tracks, as one Undo step.
- kicad_extensions: list, install or remove plugins through KiCad's Plugin and Content Manager.
- kicad_preferences: read KiCad's settings by dotted path, or change them. set is refused with reason:"tool_running" while KiCad runs.
- kicad_cancel_run: stops a background Freerouting job. Nothing from that run reaches the board.
- kicad_physical_properties: answers not_supported, because KiCad has no materials or masses on a part.
- Standard's shape on existing verbs:
- kicad_sch_label, kicad_sch_no_connect and kicad_sch_wire take sheet and id. kicad_sch_label takes remove:true.
- kicad_select_items takes clear and where, and names each designator it couldn't select in failed. where:"sheet" is refused, because the Schematic Editor has no API. Changed: one unknown designator no longer refuses the whole list.
- kicad_model_check adds parts and checked, with found and hasGeometry per model.
Tested on KiCad 10.0.8 (battery 376/0/1 pass/fail/skip on DESKTOP-BAR6S0F).
1.0.99 (2026-11-02 21:18 UTC)
NATIVE (Rust) build. 1.0.99: fourteen more of the standard's verbs under their own names, and update_pcb and teardrops in the standard's shape.
- kicad_read_board: the whole board in one read: components, nets, layers, copper, rules, occupancy, outline. sections picks some, limit caps each list and truncated names the capped ones.
- kicad_read_schematic and kicad_schematic_data: one sheet, for filePath or the sheet open in the Schematic Editor.
- Positions are mils from the sheet's lower-left grid point, y up.
- schematic_data adds each pin's number, name, electrical ordinal (with KiCad's own type name beside it), position, orientation and length.
- kicad_pcb_report: numbers instead of pixels, for a board, a .pretty library or one .kicad_mod.
- kicad_instances: every running KiCad process.
- kicad_check_dialogs: every open dialog with its buttons, category, safe action, meaning and a screenshot. It answers nothing.
- kicad_save: saves a board through KiCad's API and a schematic through the Schematic Editor's File > Save, so schematics can now be saved. It replaces the alias to kicad_save_board, which stays as it was.
- kicad_close_document: closes one board or schematic by path and never saves. Unsaved edits are discarded, as the standard says.
- kicad_close_all_documents: closes every editor. Unsaved work stays open and is listed unless save or discardUnsaved says otherwise. KiCad's project manager stays up.
- kicad_ensure_licensed, kicad_signin_status, kicad_setup_trial: the standard's onboarding answers. KiCad needs no licence or account, and ensure_licensed starts it if it is not running.
- kicad_set_models and kicad_add_models: a library symbol's footprint link, filters, parameters, comment and description. KiCad has one Footprint field, so add_models puts further footprints in the symbol's footprint filters.
- kicad_update_pcb (kicad_update_pcb_from_schematic): takes execute, allowRemovals and keepBoardOnly, and projectPath alone names the board. The reply adds preview, changeOrder, executed, afterExecute, board, dialogs and steps. execute:true refuses while removeParts is not empty unless allowRemovals or keepBoardOnly says what to do. apply:true is unchanged. A board open in KiCad is still refused: use KiCad's own Update PCB from Schematic there.
- kicad_teardrops takes the standard's arguments and defaults:
- Behaviour changes: Track to track is now on by default, and the board is now saved by default (save:false leaves it unsaved).
- tracks and tJunctions both answer KiCad's one Track to track box. vias also covers through-hole pads unless pthPads says otherwise.
- filePath is optional. force:true is refused, because KiCad has no such mode.
- The reply adds teardropsBefore, teardropsAfter, steps and dialogsLeft.
Tested on KiCad 10.0.8 (battery 370/0/1 pass/fail/skip on DESKTOP-BAR6S0F).
1.0.98 (2026-10-31 17:28 UTC)
NATIVE (Rust) build. 1.0.98: the standard's document_info.
kicad_document_info: the active KiCad document, meaning the topmost KiCad window. It reports:
- name and kind: board, schematic, library, project or model;
- modified: the leading * KiCad puts in the title;
- saved, path, project, and the sub-sheet when a schematic shows one.
- version is null, because KiCad keeps no versions.
- Read only: it opens nothing.
Where the path comes from:
- the editor's own command line, read through Adom Bridge's process list;
- the project folder, for an editor opened inside the project manager;
- KiCad's recent-file list, as a last resort.
pathFrom says which. windows[] lists every KiCad window, topmost first.
Checked live on KiCad 10.0.8: with the rp2040 project's project manager, PCB editor and schematic open, it named the schematic (topmost) with its path from the command line and the project beside it.
Tested on KiCad 10.0.8 (battery 356/0/1 pass/fail/skip on DESKTOP-BAR6S0F).
1.0.97 (2026-10-31 17:02 UTC)
NATIVE (Rust) build. 1.0.97: tested on KiCad 10.0.8, and every build now records the KiCad its battery ran on.
- KiCad 10.0.8: the test laptop was updated from 10.0.7 through the bridge's own kicad_tool_update apply (the official installer, per user, no UAC). This build's full battery ran on 10.0.8.
- Release records the tested KiCad: build_native_release.py --battery refuses a failed, partial or foreground-grabbing run, and refuses a run that tested another bridge version. Otherwise it writes the result:
- into the manifest as testedWith {kicad, battery, target, at}, which carries to public on promotion;
- into the release notes.
- kicad_readiness: testedKicad is the KiCad this build's battery passed on (null in a dev build). newerThanTested is true when the installed KiCad is newer.
- The battery report records the KiCad and bridge it tested (report.json "tested", and the report's heading).
Tested on KiCad 10.0.8 (battery 355/0/1 pass/fail/skip on DESKTOP-BAR6S0F).
1.0.96 (2026-10-30 23:02 UTC)
NATIVE (Rust) build. 1.0.96: three more standard verbs answered fully: net_connections, remove_items and doc_params (standard 0.30.4).
- kicad_net_connections: every pad with its net and owner (U1.3) in mils. Per net it gives the span and the airline length: the minimum spanning tree over its pads, the shortest copper a router could need.
- kicad_remove_items: deletes free tracks, arcs and vias given by their geometry, exactly as kicad_routing_state reported them (the standard's y-up frame; frame:"kicad" for KiCad's own).
- One result per item: ok, or err:not found.
- An open board takes it as one Undo step; a closed board is written with a backup.
- expectedRevision is optional, and the live edit still refuses a board that changed while it was prepared.
- kicad_doc_params: parameters KiCad's title block has no field for (DrawnBy, DocumentNumber, ...) are now kept as the project's text variables, which the title block and any text show as ${Name}. The reply lists them all as params, with the standard's set and saved. Before, those parameters were reported as notStored.
1.0.95 (2026-10-30 21:41 UTC)
NATIVE (Rust) build. 1.0.95: the standard's cross_check from its engine, eleven verbs that were partial under other names, now under their own, and KiCad found on any drive (engine 0.24.0, standard 0.30.0).
- kicad_cross_check: compares the schematic's designators with the board's, computed by the standard's engine.
- The reply gives matched, onSheetNotOnBoard and onBoardNotOnSheet.
- The sheets are read through KiCad's own netlist of the whole hierarchy. The board is read from the open PCB editor when it serves the board, otherwise from the file.
- sameProject (with a _warning) says when the sheet and the board sit in different folders.
- Checked: on a copy of the rp2040 project with C1 deleted from the board, cross_check names C1 as on the sheet but not the board, and the matched count drops by one.
- kicad_list_library: the symbols in a .kicad_sym or the footprints in a .pretty folder, the kind taken from the path (data.names, data.count).
- kicad_open_document, kicad_open_project, kicad_activate_document: open or bring up a board, schematic or project by path in the background. A board opened this way is the one the PCB editor's API serves.
- kicad_render_board_layers: board layers rendered to PNG or SVG through kicad-cli without a window.
- Fourteen presets (copper, silkscreen, mask and paste of either side, outline, drill at real size, assembly, fabrication), or a layer list.
- Bottom views are mirrored so they read from below, and dpi is honoured.
- kicad_export_bom: the project's BOM CSV from its root schematic, with files and outputDir.
- Fixed: KiCad installed on a drive other than C: is found (wiki #137). The bridge searches in this order:
- KiCad's registry key;
- KiCad's uninstall entries;
- Program Files\KiCad, Program Files (x86)\KiCad and \KiCad on every fixed drive;
- kicad-cli on PATH.
- bridge.json's detect globs include D: to G:, so Adom Bridge's host-app check sees such an install too.
- Library paths were already built from the detected root.
- The skill now says never to install KiCad in the Linux workspace: the bridge runs the user's own kicad-cli.
- kicad_routing_drc: KiCad's DRC on the board as the PCB editor holds it (unsaved edits included), with the project's rules and zones refilled. The reply is clean, errors, unconnected and violations[{rule, severity, description, at}].
- kicad_set_track_width: sets the width of the existing tracks and arcs on nets or a net class, optionally on one layer (top, bottom, mid N). An open board takes it as one Undo step through kicad_modify_track; a closed board is written with a backup. The reply gives byNet and drcAfter.
- kicad_footprint_primitives: one placed part's lines, arcs, pads (size, hole, net, solder and paste mask expansion in µm) and texts, in mils on the board, with other kinds counted.
- kicad_rules_by_kind: every rule the board answers to, grouped by kind and sorted by KiCad's precedence: custom .kicad_dru rules, then net classes, then Board Setup minimums.
- Engine adom-eda-checks 0.24.0 vendored unchanged (standard 0.30.0). kicad_bom stays KiCad's own: it was already exact.
1.0.94 (2026-10-30 20:46 UTC)
NATIVE (Rust) build. 1.0.94: the standard's export_3d, import_design, edit_pours, tool_update and import_step, and its schematic part verbs in their own arguments (standard 0.29.5).
- kicad_export_3d: writes the board's 3D model through kicad-cli in stl, glb, vrml, ply, brep, xao, u3d, stpz or 3dpdf.
- components:false exports the bare board. copper, silkscreen and soldermask add those layers.
- obj, 3mf, iges and other formats KiCad can't write are refused by name (not_supported), with what to use instead.
- kicad_import_design: brings an EAGLE, Altium, PADS, CADSTAR, Fabmaster, P-CAD or SolidWorks PCB board into a new KiCad project through kicad-cli's importer. The reply counts the parts and nets and gives the importer's warnings.
- kicad-cli imports the board only, and the reply says so (schematicImported: false). The schematic comes in through KiCad's File > Import > Non-KiCad Project.
- Formats KiCad has no importer for, such as OrCAD, are refused by name.
- kicad_edit_pours: changes existing pours in place: clearance, minimum width, thermal reliefs (on/off, spoke, gap) or the pad connection, priority, net, and whether islands are kept. Each pour comes back with its settings before and after.
- A closed board is written (a .adom-bak is kept) and refilled by kicad-cli, and pourState is the copper after the refill.
- On a board open in the PCB editor, each zone KiCad holds is updated in place through its API (UpdateItems: id, outline and every other setting kept) as one Undo step. The board is then refilled, and the settings are read back from KiCad (verified).
- expectedRevision is optional, and KiCad's revision or pour_state's are both accepted.
- kicad_pour_state: each pour now carries its id (the zone's uuid), which kicad_edit_pours takes.
- kicad_sch_place_part, kicad_sch_connect, kicad_sch_edit, kicad_sch_swap_part: the standard's schematic part verbs, under their own names and with their own arguments. They work alone and as kicad_sch_batch ops, and KiCad's own arguments still work too.
- Arguments: positions in mil from the grid point at the sheet's lower-left corner (y up, landing on KiCad's 50 mil grid), parts by designator, and a library as a .kicad_sym path or a table nickname plus the symbol's name.
- sch_connect takes connections [{designator, pin, net, kind: label|power|wire|noerc|port}]. sch_edit takes edits [{designator, action: move|moveBy|rotate|designator|comment|delete}].
- Each list is one write, all or nothing. The reply is in the standard's terms: connected/applied, failed, results, atMil, endMil.
- sch_swap_part wires each pin the new symbol puts somewhere else back to where the old pin ended (pinsJoined).
- kicad_sch_connect_to_net: kind "wire" draws the stub alone, with no label.
- kicad_sch_replace_symbol: joinMoved:true rejoins moved pins.
- kicad_tool_update: the standard's tool_update.
- check compares the installed KiCad with the latest stable (current, offered).
- apply installs the offered version with the official installer, per user with no UAC. It refuses while KiCad is open and lists the open documents, unsaved ones marked.
- auto reads or sets KiCad's own update check.
- kicad_import_step: answers not_supported with the reason: KiCad places 3D models only as a footprint's own model. It suggests kicad_add_body or kicad_export_step instead.
1.0.93 (2026-10-30 19:47 UTC)
NATIVE (Rust) build. 1.0.93: kicad_schematic_review checks the drawing too (engine 0.23.0, standard 0.28.0).
- kicad_schematic_review: sends the engine each sheet's drawing (sheetDrawing): wires, buses, junctions, no-connects, labels, pins and symbol boxes. The engine's drawing checks (dangling wires, floating labels, overlapping symbols, ...) now run on KiCad schematics, and the reply says drawingChecked.
- Power symbols that name a net count as power labels. Sheet pins count as hierarchical labels.
- netlist.names lists every label and port name joined into one net, so the engine can flag two names on one net.
- Checked on three real designs, where the engine agrees with KiCad's own kicad_sch_check:
- pic_programmer: one real overlap (R10 drawn over U4) and one info.
- StickHub: one info (no bulk capacitor on a rail).
- The rp2040 sample: the same 10 overlapping-symbol pairs.
- Fixed: PWR_FLAG no longer joins nets. A PWR_FLAG was read as a power symbol naming the net "PWR_FLAG", so every net carrying one became one net. This raised a false shorted_nets on pic_programmer and StickHub. Only power symbols whose pin is a power input name a net now.
- Fixed: escaped label names. KiCad writes a / in a label as {slash} (and : as {colon}, and so on) in some files. kicad_sch_check and kicad_schematic_review compared the raw text, so the labels VPP/MCLR and VPP{slash}MCLR split one net in two (a false "reaches only R18.2" on pic_programmer). Names are now read as KiCad compares them.
- Engine adom-eda-checks 0.23.0 vendored unchanged (standard 0.28.0).
1.0.92 (2026-10-30 19:04 UTC)
NATIVE (Rust) build. 1.0.92: the standard's sch_batch and log_tail shapes (#29).
- kicad_sch_batch: ops can be named by the standard's schematic verbs (sch_place_part, sch_connect, sch_edit, sch_swap_part, sch_text, sch_junction, ...) as well as KiCad's own (place_symbol, wire, ...), mixed in one batch.
- sch_connect and sch_edit run as the KiCad verb their arguments call for (wire, label, connect_to_net, no_connect; move, rotate, delete, set_property).
- sch_place_part, sch_connect, sch_edit and sch_swap_part take KiCad's arguments.
- The reply names ercBefore and ercAfter. Any op that fails, an unknown one included, is named by failedOp, and nothing is written.
- Checked: sch_place_part, sch_text, place_symbol and sch_edit ran in one write on a copy of the inverting amplifier sheet.
- kicad_log_tail: answers the standard's entries [{level, text}] and next beside lines and nextOffset.
1.0.91 (2026-10-30 18:31 UTC)
NATIVE (Rust) build. 1.0.91: three of the standard's library verbs that 1.0.90 refused are now real (#29).
- kicad_cleanup_libs (the standard's cleanup_libs): a symbol or footprint library's parts that no given project uses, and parts that repeat another part under a different name (same pins and graphics, or same pads).
- A plan by default. apply with remove takes out only the names listed, which must be in the plan unless force.
- A symbol library keeps a .bak; a footprint file moves to .pretty.removed, so both can be put back.
- A symbol another symbol extends counts as used.
- kicad_build_symbol_modes (the standard's build_symbol_modes): gives a symbol its De Morgan alternate body, KiCad's second display mode.
- The alternate drawing (rectangle, polyline, circle, arc) goes into every unit, with the standard body's pins copied and any pin shapes changed (inverted inputs). The symbol is marked as having two body styles.
- Checked: KiCad plots the alternate as mode 1 (kicad_symbol_mode).
- kicad_add_symbol_art (the standard's add_symbol_art): draws artwork inside a symbol's body rectangle, scaled to fit with a margin and centred, keeping its aspect.
- The art is given as polylines, or taken from another symbol's polylines (adom-symbol's baked chip outline).
- Checked: KiCad plots the art inside the body, with the pins untouched.
1.0.90 (2026-10-30 18:00 UTC)
NATIVE (Rust) build. 1.0.90: four more of the standard's verbs (#29: every standard verb answered on every bridge).
- kicad_swap_footprint (new; the standard's swap_footprint): puts another library footprint on one placed part.
- The part keeps its position, rotation, side, reference, fields, schematic link, DNP/BOM flags and lock.
- Pads keep their nets by number, and assigns ("9=GND") sets nets on any pad. The reply lists the pads whose net was kept and any pad left without a net.
- Checked: C1 on a copy of KiCad's pic_programmer demo went from an axial to a radial capacitor with both nets kept, and KiCad's DRC is clean.
- kicad_plate_vias (new; the standard's plate_vias): in a footprint library, every drilled pad becomes a plated hole through every copper layer when it isn't one already: a thru_hole pad on only some copper layers, or an smd pad with a drill (thermal vias written as surface pads).
- Numbered unplated holes are listed, and plated only with includeNpth. Running it again changes nothing.
- kicad_normalize_bodies (new; the standard's normalize_bodies): moves a footprint's 3D model onto its pad cluster (by its offset) when the body sits more than minShiftMm from the pads' centre. Models already on their pads are left alone.
- Checked: a SOIC-8 whose STEP sat 50 mm away was moved back onto its pads.
- kicad_symbol_mode (new; the standard's symbol_mode): one body style of a library symbol as a picture, plotted by KiCad: mode 0 the standard body, mode 1 the De Morgan alternate, per unit.
- Checked: 74LS00 in mode 1 shows the OR body with inverted inputs. A symbol with no De Morgan body refuses mode 1.
- The standard's Altium-only verbs (licence, sign-in, agent, extension, symbol-mode specs, cleanup) are now answered in KiCad's equivalents: mapped where KiCad has the job, otherwise unsupported with the reason. panel maps to kicad_send_key's View > Panels toggle; activate_document maps to kicad_open_board and kicad_open_schematic.
- The standard's Altium-only verbs now exist in KiCad and refuse with not_supported, each with the reason and what to call instead. They are add_symbol_art, cleanup_libs, build_symbol_modes, license, signin, connect_workspace, agent_start/stop/status/recover, selftest_script_error, extension_ping, install_extension and install_receipt.
- An AI that calls kicad_license learns that KiCad is GPL with no licence page (instead: kicad_license_status) rather than meeting unknown_verb.
1.0.89 (2026-10-30 17:18 UTC)
NATIVE (Rust) build. 1.0.89: camera choreography (the standard's animate_view).
- kicad_animate_view (new; the standard's animate_view): camera steps run inside the bridge, so the timing is tight enough to narrate over. Everything runs in the background.
- On the PCB editor: zoom_all, zoom_in and zoom_out, as KiCad's own actions through its API.
- In the 3D Viewer: views, orbits, rolls, pans, flip and rotate90, as its View-menu commands.
- view_3d and view_2d switch between them within one call.
- Presets: punch_in, orbit, showcase3d, flip and finale.
- Steps KiCad has no command for (isometric, ortho) are listed in skipped, never faked. The schematic lane is refused as not_supported, because KiCad 10's Schematic Editor has no API.
- Checked on the pic_programmer demo board:
- Four zoom-ins took the editor from zoom 2.84 to 20.00, centred.
- 17 3D commands ran in 6.8 s, with isometric skipped.
- The orbit preset's 36 commands ran in 5.4 s.
- kicad_lint_library: the standard's library lint (engine 0.21.1, standard #28). The bridge's structural check and KiCad's own verdict now come with the shared content rules, each finding carrying its rule and severity.
- Footprints: no pads, zero-size pads, unnumbered and duplicate pad numbers, no courtyard, origin off the part, no silkscreen, no 3D body, no description.
- Symbols: no pins, unnumbered and duplicate pins, no footprint, footprint not found, pins without pads and pads without pins, no part number.
- kicad-cli's refusals pass through as tool_refuses_file.
- Linting a symbol library alone now finds its linked footprints ("Lib:Name": a Lib.pretty beside it, else KiCad's footprint library tables), so pins are checked against pads. Those footprints' own findings stay out, since they aren't the library being linted.
- KiCad's paste-only apertures (pads with no copper) and unplated holes need no number and no pin.
- A kicad-cli that doesn't answer in time is now reported as "verdict unknown", no longer as KiCad refusing the file.
- Checked: KiCad's Package_SO library (401 footprints) has no errors, and its split exposed pads are quiet: engine 0.21.1 counts touching pads with the same number as one land.
- Checked: a 6-pin symbol linked to a SOT-23-5 gives "pin 6 has no pad on Test:SOT-23-5".
- kicad_update_footprints_from_library: the standard's reply (#27, now a core verb).
- Each row carries footprint and library; the count is also given as differs.
- padsChanged lists what changed (type, shape, position, rotation, size, drill, layers).
- Engine: adom-eda-checks 0.21.1 (EDA Bridge Standard 0.24.2).
1.0.88 (2026-10-30 16:11 UTC)
NATIVE (Rust) build. 1.0.88: KiCad 10's design variants (the standard's variants).
- kicad_variants (new): which parts are fitted on which build, on the project's own files.
- Lists every variant with its not-fitted parts, its changed fields (alternates) and its description.
- Makes or changes a variant: marks parts not fitted, or puts them back. Describes or removes one.
- It writes what KiCad 10 writes: the variant list in the .kicad_pro, and each part's variation inside its instance on whichever sheet holds it. A .bak is kept beside every file written.
- KiCad reads the result back: kicad-cli's netlist for the variant must mark exactly those parts DNP, or the call fails with verify_failed.
- Unlike Fusion's read-only list, KiCad's verb edits variants. Field changes (another Value in a variant) are listed but made in KiCad's own variant editor.
- Checked on a copy of KiCad's pic_programmer demo (two sheets):
- Lite with P1, C1 and R1 not fitted: KiCad marks the same three DNP.
- R1 put back: C1 and P1 are left.
- A second variant with D1: matches.
- Lite removed: only Pro is left in the project.
- kicad-cli's BOM for Lite leaves out C1 and P1.
- kicad_sch_zoom (new; the standard's sch_zoom): finds parts on a schematic sheet and frames them. It's the schematic half of cross-probing; kicad_zoom_to is the board half.
- Answers where each part sits (mm) and which ones the sheet doesn't place.
- The proof frame is KiCad's own plot of the sheet, cropped to the parts with a margin and each part outlined.
- KiCad 10's Schematic Editor has no API, so the frame is a plot of the saved sheet and the open editor's view isn't moved.
- Checked: C1 on the pic_programmer root sheet, and U1, P2, C6 and C7 together on its pic_sockets sub-sheet, each outlined in the plot.
1.0.87 (2026-10-29 22:00 UTC)
NATIVE (Rust) build. 1.0.87: refusals the caller can fix no longer say they may be a bridge bug.
- Every verb: the "THIS MAY BE A KICAD BRIDGE BUG ... file an issue" line no longer appears on a refusal the caller fixes.
- That covers a missing or bad argument, a name or file that isn't there, unsaved changes, a stale revision, a DRC refusal, no simulation model, a missing reason, and not supported.
- Unexpected failures still carry it.
- Before, kicad_current_capacity without its nets told the AI to file a bug for its own missing argument.
- kicad_simulate: noise analysis (standard #23).
analysis {type: "noise", source, output, reference?, sweep, points, start, stop}runs ngspice's .noise.- It answers the onoise and inoise spectra (V/rtHz) as signals, and totals {onoise, inoise} in V.
- Checked: an RC filter's output noise is 4.0714 nV/rtHz, the resistor's sqrt(4kTR). The total is 0.2035 uV against sqrt(kT/C) = 0.2036 uV.
- kicad_simulate: Monte Carlo (standard #23).
monteCarlo {runs, distribution: uniform|gaussian, seed, tolerances: {resistor, capacitor, inductor, dcSource} %}.- Every part of a kind with a tolerance is drawn again for each run. Uniform draws stay within the tolerance; gaussian draws use sigma = tolerance/3, clipped to the tolerance.
- Each run's step lists the values drawn, and the same seed draws the same values.
- Transistor and digital tolerances are refused with not_supported.
- Checked: on an inverting amplifier, every run's gain matches 20*log10(R2/R1) from its own drawn values, less the op-amp model's finite-gain error.
- kicad_height_check and kicad_placement_check: turned parts (engine 0.20.0, standard #26). A part turned off the 90° grid now sends its body's real rectangle, so it no longer collides through its bigger bounding box.
- Checked: StickHub, with a 45° LQFP and its decoupling caps, went from 70 false collisions to 1.
- That 1 is a crystal tucked into the LQFP's lead-free corner, which a body box (leads included) can't tell apart. KiCad's courtyard DRC passes.
- Engine: adom-eda-checks 0.20.0 (EDA Bridge Standard 0.23.0).
1.0.86 (2026-10-29 21:25 UTC)
NATIVE (Rust) build. 1.0.86: fixes found by testing 1.0.85 on real boards.
- kicad_review_board: KiCad's per-pin "unconnected-(U5-PB0-Pad16)" nets now count as no net, the way kicad_schematic_review treats them.
- KiCad gives every pin the schematic leaves unconnected a net of its own, so each one used to come back as a one-pad net warning.
- Checked: the ESC board went from 23 such warnings to a clean review. The rp2040 sample's real findings are unchanged.
- kicad_review_board: the vendor part number and datasheet checks now read the symbols' fields. The parts sent from KiCad's netlist used to carry none, so every part was flagged even when it had Mouser, DigiKey and LCSC numbers.
- Empty fields, and KiCad's "~" for no datasheet, don't count.
- Checked: on a copy of the rp2040 sample, giving C1 its Mouser, DigiKey and LCSC numbers and a datasheet clears both of its findings.
- kicad_footprint_from_land_pattern (engine 0.19.1, standard #25, found testing 1.0.85):
- SOT-23-5's pins 4 and 5 now line up with pins 1 and 3 (±0.95 mm). Before, they sat 0.95 mm apart, centred, so the part did not fit.
- The courtyard holds the pads and body only, so a 7 mm BGA's is symmetric at ±3.75 mm instead of stretching to the pin-1 dot.
- Engine: adom-eda-checks 0.19.1 (EDA Bridge Standard 0.22.2).
- Verb tests: the test run never overlaps another bridge's test run on the same machine. It waits up to 30 minutes, then refuses (#112).
1.0.85 (2026-10-29 20:44 UTC)
NATIVE (Rust) build. 1.0.85: simulation sweeps and the parts a run left out, and footprints from a datasheet's land pattern laid out by the standard's engine.
- kicad_footprint_from_land_pattern: the standard's engine lays the footprint out, and KiCad's own writer turns it into the .kicad_mod and the 3D body box.
- The layout is the same as before: KiCad's code and the engine's both came from the Altium bridge, line for line. One copy now, so the engine's fixes reach KiCad.
- It covers pad numbering for chip, dual, SOT, quad and BGA packages, the exposed pad, the courtyard, silkscreen clear of the copper with a pin-1 dot, and a fab outline with a pin-1 chamfer.
- Replies carry engine. A missing number is still named ("dual needs padLength (mm)").
- Checked: a 3x3 mm QFN-16 with exposed pad was built live and read back by KiCad with 17 pads and its 3D model.
- Engine: adom-eda-checks 0.19.0 (EDA Bridge Standard 0.22.1).
- A width rule with only a minimum (Fusion's EAGLE rules) now counts as the board's track width.
- The engine's new panelize and teardrops plans are not used here: KiCad keeps its own kicad_teardrops (KiCad's own teardrop generator) and kicad_panelize.
- kicad_simulate and kicad_export_spice: notSimulated (standard #23, as Altium 0.2.82 reports it). These are the sheet's parts that KiCad left out of the netlist because they have no simulation model.
- A partly modelled sheet still runs, and the reply says which parts the result does not cover. KiCad writes a part with no model as a stub with no nodes (J1 __J1), which made ngspice refuse the whole circuit; the run now leaves those stubs out.
- A sheet where no part has a model refuses with no_model instead of an ngspice error.
- Parts the designer excluded from simulation are left out on purpose and are not listed.
- Checked: an RC with a connector on its output runs and names J1; a sheet of two connectors refuses no_model.
- kicad_simulate: sweeps (standard #23, as accepted from Altium). Arguments:
sweep {parameter, start, stop, step, scale?}andtemperatures {start, stop, step}.- ngspice has no .step, so the circuit runs once per value: a part's value ("R4") is set with alter, a model parameter ("Q1.BF") with altermod on the part's model, and the temperature with .temp.
- Each run's signals carry step ("R1 = 2k", "T = 85"); the reply says how many runs there were (at most 50).
- A part that isn't in the netlist, or a model the netlist doesn't define, is refused with bad_args, never one run passed off as the sweep.
- Checked live:
- R1 at 1k and 2k puts the RC filter's corner at 1588 Hz and 794 Hz.
- A diode's forward voltage is 753, 696 and 639 mV at -10, 25 and 60 °C.
- Its emission coefficient N at 1 and 2 gives 0.69 V and 1.38 V.
1.0.84 (2026-10-29 19:49 UTC)
NATIVE (Rust) build. 1.0.84: a whole-board design review, and the standard's engine 0.17.2.
- kicad_review_board (new; the standard's review_board): one read of the board, and of the schematic beside it through KiCad's own netlist, reviewed by the standard's engine.
- Finds duplicate designators, parts off the board or near its edge, placeholder values on the board and the sheets, one-pin nets, parts without a footprint, missing vendor part numbers and datasheets, and disabled or missing design rules.
- Board Setup's clearance, track width and minimum through hole go in as the board's rules. KiCad's DRC always checks shorts, clearance, track width and hole size, so no rule class reads as missing on a KiCad board.
- skipped and notImplemented name what it could not judge (a placement grid needs gridMm; decoupling is kicad_schematic_review's job).
- Checked: the rp2040 sample's 12 PIN** test points come back as a duplicate designator, its 20 parts without vendor part numbers as warnings.
- kicad_schematic_review: each part now carries its value and comment too.
- Engine: adom-eda-checks 0.17.2 (EDA Bridge Standard 0.20.2).
1.0.83 (2026-10-29 19:26 UTC)
NATIVE (Rust) build. 1.0.83: a schematic review before the board is updated, and the standard's engine 0.16.0.
- kicad_schematic_review (new; the standard's schematic_review, which KiCad answered only in part before): reviews every pin against KiCad's own netlist of the design, with each pin's electrical type.
- Errors: power pins on no net, outputs driving each other.
- Warnings: pins on no net, one-pin nets, inputs nothing drives, and IC supplies with no decoupling capacitor to ground.
- KiCad's single-pin unconnected-(...) nets count as no net, and a pin with a no-connect flag is expected to be unconnected.
- Checked: a wired RC filter is clean; the unwired rp2040 sample shows its 5 unconnected power pins and 2 supplies without a capacitor.
- Engine: adom-eda-checks 0.16.0 (EDA Bridge Standard 0.19.0). KiCad keeps its own route_pair, length_tune, auto_classes, silk_designators, pin_pad_check and find_space: they work on KiCad's real courtyards and its live editor.
1.0.82 (2026-10-29 18:43 UTC)
NATIVE (Rust) build. 1.0.82: five more of the standard's app-tier verbs, and KiCad's own Python from the bridge.
- kicad_eval: a Python snippet run with KiCad's bundled Python and its pcbnew module, headless.
- With filePath the board is loaded as
board, and the snippet'sresultcomes back as JSON. - Checked: 149 footprints and 83 nets read in 0.4 s; a failing snippet returns its traceback.
- With filePath the board is loaded as
- kicad_run_script: a .py of your own run the same way, with arguments; stdout, stderr and the exit code come back.
- kicad_foreground: brings a KiCad window to the person. It needs a reason written for them, captions it first, and refuses without one.
- kicad_dialog_log: every dialog the bridge's sweeps dismissed since it started, newest last.
- kicad_license_status: KiCad's licence in plain words: GPL-3.0-or-later, no seat, sign-in or trial.
1.0.81 (2026-10-29 17:52 UTC)
NATIVE (Rust) build. 1.0.81: the standard's engine 0.12.2 and two assembly-check fixes.
- kicad_assembly_check (standard #24):
- pads sharing one centre (one land drawn as several pads) no longer read as a 0 mm pitch;
- a footprint with no pads (a logo) no longer counts as a part, so a bottom-side logo no longer fails "parts on one side only".
- kicad_plan_route (engine 0.12.2): routes are smoothed into straight and 45-degree segments with the same clearance (smooth:false turns that off). A pour holding the route's own end pad is exempt from avoidPours (avoidExempt), and planner reports withoutAvoid.
- Engine: adom-eda-checks 0.12.2 (EDA Bridge Standard 0.15.2).
1.0.80 (2026-10-29 17:35 UTC)
NATIVE (Rust) build. 1.0.80: framing the view on a part or a net that works with KiCad in the background (wiki #121), and the standard's engine 0.11.0.
- kicad_zoom_to (new; the standard's zoom_to): frames the open PCB editor on parts ({refs}) or a whole net ({net}), or fits the board.
- It runs KiCad's own Zoom to Selected Objects through its API, so the view really moves while KiCad stays in the background. A menu command posted to a background window was acknowledged but did not move it.
- The selection it makes is cleared afterwards (keepSelection keeps it), and the API answers normally right after.
- Checked: U5 framed from zoom 4.5 to 33 in the background; a net and the whole board too.
- kicad_select_net / kicad_select_items: their hints now point to kicad_zoom_to.
- Engine: adom-eda-checks 0.11.0 (EDA Bridge Standard 0.14.0). KiCad keeps its own IPC-2581 exporter.
1.0.79 (2026-10-29 17:03 UTC)
NATIVE (Rust) build. 1.0.79: simulation in the EDA Bridge Standard's shape (standard 0.14.0, #23).
- kicad_simulate takes and answers the standard's simulate:
- analysis as {type: op | dc | ac | tran | raw, ...};
- probes by net ({net: "OUT"}) and source current ({current: "V1"});
- signals[{signal, x, y, xUnit, yUnit, phase}] with each probe's own points. points is a ceiling that always keeps the first, last and extreme points, and AC phase is unwrapped;
- engine names the ngspice and KiCad versions ("ngspice 46 (KiCad 10.0.7)").
- SPICE text, V(/OUT) probes and the earlier fields still work.
- kicad_export_spice says its dialect (ngspice).
- Both are now standard verbs (simulate, export_spice) rather than KiCad's own.
1.0.78 (2026-10-29 16:41 UTC)
NATIVE (Rust) build. 1.0.78: SPICE simulation from a KiCad schematic, headless, through the ngspice KiCad installs.
- kicad_simulate (new, wiki #89): runs a sheet through ngspice, the simulator KiCad itself uses.
- Analyses: transient, AC, DC sweep or operating point, given in the call or carried by the schematic.
- Probes are node voltages V(/NET) and source currents I(V1). Each comes back downsampled with its first, last, min and max (AC as dB and phase), and as a CSV file.
- ngspice runs in a child process, so a circuit that crashes it never takes the bridge down, and a failed analysis returns ngspice's own message.
- Checked: an RC low-pass of 1k and 100n is -2.99 dB and -44.9 degrees at 1.58 kHz, and passes 0.85 of a 1 kHz sine.
- kicad_export_spice (new): KiCad's own SPICE netlist of a sheet, with its elements, its analyses and the model files it includes.
- Engine: adom-eda-checks 0.10.4 (standard 0.13.4): plan_route keeps a pour holding the route's own end pad out of avoidPours, echoes its pour settings, and smooths grid staircases into straight and 45-degree segments.
1.0.77 (2026-10-28 21:57 UTC)
NATIVE (Rust) build. 1.0.77: fanout plans that are safe on a routed board, decoupling caps that leave room for the fanout, and the standard's engine 0.10.3.
- kicad_plan_fanout: now planned by the standard's engine, safe on a routed board (standard #22):
- pins whose net already reaches the pad are skipped (includeRouted plans them anyway);
- conflicts are measured against other nets' pads, tracks, arcs and vias;
- an exposed pad's via grid steps round holes already there;
- crossesPours names the pours the plan runs into.
- Each call comes back ready for kicad_route_net. The old argument names still work.
- kicad_place_decoupling: leaves room for the IC's fanout (leaveFanout, default true): no cap pad lands on the escape stubs or vias of the IC's other pins. Checked on the ESC board's U5.
- Fix: 1.0.76's fanout conflict check missed every stub starting at a pad and measured a stub against a pad as an outline. It is now correct, with regression tests.
- kicad_plan_route (engine 0.10.3): avoidPours takes a list of nets, and pourCost makes crossing pours a soft cost.
1.0.76 (2026-10-28 21:31 UTC)
NATIVE (Rust) build. 1.0.76: fanout conflicts, routes that know the pours, the tour template back, and the standard's engine 0.10.0.
- kicad_plan_fanout: conflicts[] lists every planned via and stub closer than the clearance to another net's pad anywhere on the board, measured by the pad's real outline. Vias count on every layer, stubs on their own layer (standard #22).
- kicad_plan_route (engine 0.10.0, standard #21):
- crossesPours names other nets' pours the route runs through, and avoidPours:true keeps it out of them;
- through vias are checked on every copper layer;
- the board's strictest clearance rule decides.
- kicad_place_decoupling: a cap the plan can't move keeps its spot, so no other cap is planned onto it.
- Tour template (wiki #136): tour-pack/template is rebuilt: one AdomTour R_AdomTour on a sheet, a small board and a project. The default kicad-tour pack has its files again.
- KiCad 10.0.7 opens all three; the only ERC/DRC findings are the unconnected resistor and the AdomTour library, which the tour installs.
- The 7 schematic unit tests that read it pass again.
1.0.75 (2026-10-28 21:05 UTC)
NATIVE (Rust) build. 1.0.75: decoupling caps sorted by the IC they belong to, routes planned at the board's net class, and the standard's engine 0.7.0.
- kicad_place_decoupling: by default it now leaves out two kinds of cap, listed in leftOut[] (standard #22):
- signal_net: a net not named like a supply with only one cap to ground, such as a crystal's load cap;
- nearer_another_ic: a cap nearer another IC's pin on the same net.
- On the ESC board, U1 no longer takes every +VBAT cap: they split between U1 and U2. Naming caps still places them as asked.
- A through-hole pad of a part on the other side now blocks the spot too.
- kicad_plan_route: the project's Default net class goes to the engine as the board's width and via rules, and planner.widthFrom / viaFrom say which rule set them.
- kicad_open_board: when KiCad's API serves another PCB editor's board, it now says so (api_serves_another_board), not "a different board with the same file name".
- Engine: adom-eda-checks 0.7.0 (EDA Bridge Standard 0.10.0).
1.0.74 (2026-10-28 20:40 UTC)
NATIVE (Rust) build. 1.0.74: 3D bodies made from package dimensions and routes planned between pads, both from the standard's engine 0.6.0.
- kicad_generate_body (new): a part's 3D body from its package family and the datasheet's JEDEC letters, to IPC-7351 proportions, with an optional marking on top.
- Families: chip, SOIC, QFN, QFP, BGA, SOT-23, DFN, MELF, can, crystal and header.
- The engine writes the STEP. With libraryPath it goes in .3dshapes, and footprintName attaches it.
- Checked: a SOIC-8 marked LM358 sits on its footprint's pads at 1.75 mm.
- kicad_plan_route (new): a path for one net between two pads, around the board's copper and inside its clearance rules, on the layers allowed, with vias where they help. Nothing changes.
- routeNet is kicad_route_net's own arguments, ready to run.
- Checked on the ESC board: /DRV_GHC (R12.1 to U4.13) is a 2.5 mm F.Cu path, and kicad_route_net took it unchanged with no new DRC error.
- Engine: adom-eda-checks 0.6.0 (EDA Bridge Standard 0.9.0). These were KiCad's last two standard verbs outside the app tier.
1.0.73 (2026-10-28 20:13 UTC)
NATIVE (Rust) build. 1.0.73: parts framed in KiCad's own render, a stricter painted-canvas check, and the standard's engine 0.4.1.
- kicad_render_board ref / refs (wiki #105): frames those parts in KiCad's own renderer.
- The camera pivots on the parts' pad centre and zooms to fit them with marginMm around; data.framed reports the pivot and zoom.
- rotate "-45,0,45" gives an isometric view.
- Checked on the ESC board: J1 is centred, top, bottom and iso; J1 with Q1 frames both.
- canvasRendered (wiki #100): a canvas now also needs 10% of its sampled rows to vary.
- A blank white 3D viewer with one black strip (John's capture) had passed; it is now reported as not drawn.
- Real views measured 33 to 100%.
- kicad_footprint_models: the battery now changes a model's offset live, reads it back and restores it (wiki #101).
- Engine: adom-eda-checks 0.4.1 (standard 0.7.1). placement_check lists a part under a raised one as
stacked, not as an overlap.
1.0.72 (2026-10-28 19:28 UTC)
NATIVE (Rust) build. 1.0.72: four more checks from the standard's engine 0.4.0 (EDA Bridge Standard 0.7.0), and a placement review.
- Engine: adom-eda-checks 0.4.0, vendored unchanged. Every engine reply now carries the engine's own
enginefield instead of a version written by hand. - kicad_thermal_vias and kicad_via_fence: planned by the engine, as all three bridges now do (standard #18).
- The via comes from the project's Default net class, and the fence's clearance from the board's largest clearance rule.
- KiCad's DRC still runs before any via is placed, live or in the closed file.
- kicad_height_check: computed by the engine from kicad_bodies;
completesays whether every part had a body (standard #19). - kicad_placement_check (new): a placement review before routing, from the engine with the parts' 3D bodies.
- It finds parts whose pads and bodies overlap on one side, parts off the board or over its edge, pads near the edge, and parts on a mounting hole.
1.0.71 (2026-10-28 19:00 UTC)
NATIVE (Rust) build. 1.0.71: pictures of library parts, and layer visibility in the open board.
- kicad_library_views: each part in a library drawn for review, as image files, headless (kicad-cli; nothing opens).
- The symbol, one PNG per unit; the footprint with its pad numbers; the 3D body seated on its pads, an isometric view zoomed out for a tall body.
- The device view: an SVG table of every symbol pin against a footprint pad, with any pin without a pad and any pad without a pin listed.
- From a .kicad_sym the footprint is the symbol's Footprint field; from a .pretty folder, symbolLibraryPath gives the symbol.
- A footprint with no model, or a model file that does not resolve, is reported ok:false for 3d, never drawn empty.
- kicad_set_layer_visibility: shows or hides one layer of the open board (by name or layer id) and reads it back.
1.0.70 (2026-10-28 17:55 UTC)
NATIVE (Rust) build. 1.0.70: schematics drawn from a netlist, a plan-only library-bundle install, and the standard's engine 0.2.1.
- kicad_build_schematic: a new sheet (and project) from a parts list and a netlist with library symbols.
- One column per block, a stub and a net label on every connected pin, and the title block filled.
- Then KiCad's own netlist of the sheet is compared with the nets given, pin by pin, and ERC runs.
- kicad_install_library_bundle planOnly:true (wiki #106): installs nothing.
- It answers the steps with time estimates, and per part the evidence the install will give: symbol always, footprint when the bundle has it, 3d when its model is in it.
- The real install now reports steps[] with the same ids.
- Engine: adom-eda-checks 0.2.1 (EDA Bridge Standard 0.5.1), vendored unchanged; nothing in KiCad's checks changes.
- The checks' engine field had kept saying 0.1.2 since 1.0.67; a test now ties it to VENDOR.md.
1.0.69 (2026-10-28 17:28 UTC)
NATIVE (Rust) build. 1.0.69: length tuning, mouse-bite panels, silkscreen prep, component classes, new boards from footprints, and schematic sheets read from the file.
- kicad_panelize separation:"tabs": the copies stand gapMm apart (2 mm default) inside a frame with rails all round.
- Each board's edges are broken at its tabs on Edge.Cuts (the rout path), and every tab carries five 0.6 mm mouse-bite holes on the board side.
- The tab layout and JLCPCB's panel rules (for tabs and for V-score) are the Altium bridge's, and the reply now carries them as jlcpcb.rules, with boardsAt and nearestCopperToEdge.
- kicad_build_board: a new board from a parts list and a netlist: the outline (a rectangle with rounded corners, or a polygon), every footprint from its library by its own origin, pad nets set, read back pin by pin.
- kicad_test_board: one footprint or a ';' list from a library on a new board, or added to an existing one.
- kicad_read_sheet_file: a .kicad_sch's parts read from the file (designator, symbol, value, uuid, unit, position, fields and pins), one entry per placed unit.
- kicad_length_tune: lengthens a net to targetMm, or to matchTo's length (pair skew, a byte lane). It draws a serpentine of square bumps in its longest straight track with room on one side, sized to add exactly the missing length, clear of other copper and the edge. Live as one Undo step, or in the closed file, after KiCad's DRC shows no new error.
- kicad_silkscreen_prep: on a closed board, in one call:
- turns on KiCad's own clipping: the Gerbers subtract the solder mask from the silkscreen;
- deletes silkscreen lying outside the board;
- moves designators that sit on pads;
- reports KiCad's silk DRC counts before and after.
- kicad_component_classes: lists, makes or removes KiCad 9+ component classes. An optional room is a rule area plus a custom DRC rule that flags any member outside it. Both were checked against KiCad 10.0.7's DRC.
1.0.68 (2026-10-28 16:15 UTC)
NATIVE (Rust) build. 1.0.68: ordering and footprints, five more of the EDA Bridge Standard's verbs.
- kicad_bom: the schematic's parts merged with the board, one line per MPN, checked for what an order lacks.
- Writes bom.csv, JLCPCB's BOM and CPL, the Mouser and DigiKey BOM-tool files and bom.json.
- The grouping and the field names matched across libraries are the Altium bridge's, so the files read the same in both tools.
- kicad_assembly_check: the board against JLCPCB's Economic and Standard assembly tiers, and the cheapest one it passes. Parts the line never places (excluded from BOM or position files, DNP, board-only) are left out.
- kicad_jlcpcb_order: in one folder:
- the fab check;
- the Gerbers and drill, zipped;
- the BOM and CPL;
- the assembly tiers;
- the order-form values;
- every issue in one list, with
ready.
- kicad_footprint_from_land_pattern: a footprint from a datasheet's land pattern (chip, SOIC/DFN, SOT, QFP/QFN, BGA, exposed pad), with silkscreen clear of copper, pin-1 marks, the courtyard and a 3D body box.
- kicad_silk_designators: every reference designator placed upright beside its part, clear of pads, bodies, existing silkscreen and the other labels, never below the board's minimum text height.
- A closed board gets the labels written into the file. KiCad's DRC checks the result first, and a label it flags is reported, not written.
- A board open in KiCad is moved live as one Undo step, unless its footprints carry KiCad 10's units block: then it refuses, nothing changed (see below).
- Fixes:
- kicad_silk_fields_batch no longer drops footprints' units blocks. KiCad 10.0.x moves a field only by sending its whole footprint back, and loses the footprint's units block (pin groups) doing so. Such a move now refuses with field_move_drops_units, nothing changed, unless allowUnitsDrop:true.
- kicad_silk_state gives a part with a round courtyard its real body box, not a flat line.
- The netlist reader keeps symbol fields and DNP flags for the BOM.
1.0.67 (2026-10-27 22:24 UTC)
NATIVE (Rust) build. 1.0.67: board checks, the EDA Bridge Standard's checks tier: 14 verbs that check a board and place the vias a check asks for.
- The standard's shared engine (adom-eda-checks, vendored unchanged): kicad_return_path (with a ready kicad_apply_zone_plan that closes each gap), kicad_copper_balance, kicad_impedance (with ready kicad_custom_rules width and pair rules), kicad_current_capacity, and kicad_fab_check: the board against a fab's record from adom/pcb-design-rules (fab:"jlcpcb"), naming the page and the date it was read. kicad_validate_for_fab stays as KiCad's own DRC check. kicad_silk_state also answers the standard's shape (components, lines, texts with x, y and size).
- Computed by the bridge: kicad_net_lengths (pair skew, matched-length groups), kicad_check_orientation, kicad_find_space, kicad_height_check (3D heights, regions, collisions), kicad_pin_pad_check (symbol pins against footprint pads), kicad_auto_classes (net classes from names, written with apply).
- Vias: kicad_thermal_vias fills an exposed pad and kicad_via_fence lines fast tracks and/or the board edge with ground vias. Both run live as one Undo step, or into the closed file, and only after KiCad's DRC (pours refilled) shows they add no error.
- kicad_board_report: every check, plus DRC, ERC, the board against the schematic and the fab's limits, with a rendered picture, in one HTML file.
- Fix: kicad_update_pcb_from_schematic no longer reports nets with a slash in their name as changed: the board writes /VPP{slash}MCLR and the netlist /VPP/MCLR. On KiCad's pic_programmer demo it reported 11 false changes, and apply would have renamed those nets.
1.0.66 (2026-10-27 21:14 UTC)
NATIVE (Rust) build. 1.0.66: teardrops and V-score panels, two more of the EDA Bridge Standard's native verbs.
teardrops: adds or removes teardrops with KiCad's own Edit > Edit Teardrops dialog (KiCad's API has no teardrop call), on PTH pads, SMD pads and vias, optionally track to track or the selection only. It counts the teardrops before and after and returns the board's new revision. The board's default teardrop shapes are used.
panelize: steps a rectangular board into a V-score panel as a new board file:
- rows x cols copies, each with its nets renamed B-;
- one outline with rails, V-cut lines on Cmts.User, and three tooling holes and three fiducials;
- KiCad's DRC on the panel, compared with the board's own: newErrors counts only what the panel adds.
A shaped board is refused, because it needs mouse bites.
1.0.65 (2026-10-27 20:14 UTC)
NATIVE (Rust) build. 1.0.65: any library footprint can now be added to a board open in KiCad, plus four of the EDA Bridge Standard's native verbs.
Live adds without a copy on the board. add_footprint and add_mounting_hole build the part from its library text as KiCad's protobuf items (commit:"create-items", one Undo step): pads, graphics, texts, fields and 3D models.
- When the same library footprint is already on that side of the board, KiCad's own encoding of it is still copied.
- Checked on KiCad 10.0.7: stock parts with through-hole and SMD pads, at 0, 45, 90 and 270 degrees and on the back, came out the same as the closed-file add. DRC reports no library mismatch for them.
- A footprint with custom-shape pads, mask or paste margins, or zones inside still refuses with live_create_unsupported and says why.
New standard verbs:
- compile: ERC and the netlist, with messages counted by class;
- list_installed_libraries: every symbol and footprint library KiCad loads, with missing ones flagged;
- replicate_layout: one channel's placement onto matching channels through move_footprint, one Undo step;
- diff_pairs: the pairs KiCad's router recognises by name, and the net class that sets their width and gap.
1.0.64 (2026-10-27 19:27 UTC)
NATIVE (Rust) build. 1.0.64: adds to a board open in KiCad, two fixes for footprints KiCad rebuilds over its API, and 17 of the EDA Bridge Standard's core verbs.
Adding items to an open board. KiCad 10.0.x creates nothing from text over its API, so the bridge now encodes the new items as KiCad's protobuf items itself (commit:"create-items", one Undo step):
- board_outline and import_svg are created live;
- add_footprint (with duplicateOf and count) and add_mounting_hole create a part live when the same library footprint is already on that side of the board with the same pads and graphics: the bridge copies KiCad's own encoding of it, with fresh ids, the new pose, reference, value and pad nets;
- anything else, a footprint the board lacks and update_footprints_from_library included, still refuses with live_create_unsupported, now with liveCreateWhy.
Footprints KiCad rebuilds over its API (#126, #129). KiCad stores every footprint it rebuilds without a polygon's repeated closing point, which DRC then reports as lib_footprint_mismatch:
- moves, live field edits and live part edits now name those parts in closingVerticesDroppedByKiCad, with how to restore them;
- a live field move (silk_fields_batch) no longer fails otherBoardDataVerified because of it.
New standard verbs:
- footprint libraries: copy_footprint, rename_footprint, remove_footprint, xcopy_footprint, add_body;
- symbol libraries: clone_symbol, rename_symbol, set_params, set_visibility, symbol_prims;
- sheets: place_on_sch, doc_params, sheet_params (the BOM write-back onto placed parts), part_parameters;
- the board: layers, silk_state, ripup_nets.
1.0.63 (2026-10-27 18:18 UTC)
NATIVE (Rust) build. 1.0.63: the EDA Bridge Standard's shapes for the 47 verbs KiCad brought to the standard (standard 0.3.0). KiCad's own names and arguments keep working.
- Standard names: render_board_3d, remove_parts, edit_parts, align_parts, remove_graphics, read_footprint, export_library_part, create_part_project. kicad_edit_footprint with library arguments edits the library footprint (fp_edit), as the standard means it.
- Standard arguments:
- sheet and project paths;
- id/ids for KiCad's uuids;
- mm-named numbers;
- bomFields on IPC-2581;
- at and box on import_svg and copy_routing.
- Lists are one write: sch_connect_pins pairs, sch_bus_entry entries, sch_edit_label edits, sch_text texts and sch_junction add+remove run as one kicad_sch_batch. kicad_edit_parts takes
edits: [{ref, ...}], a different edit per part, in one undo step, live or on the file. - y up: frame:"standard" on all 47. Sheet verbs answer y up too; sch_pins also answers one flat pins list.
- estimate_cost names its price source (the bridge's built-in JLCPCB-style rates; no check date is recorded) and lists prices per quantity.
- create_part_project refuses to overwrite an existing project unless overwrite:true.
- kicad_describe marks these verbs with standardShape.
- The release script now pushes only reference/kicad-.json to the standard, which standard-lane owns.
- Battery: phase 9 runs the standard shapes on a real KiCad.
1.0.62 (2026-10-27 16:30 UTC)
NATIVE (Rust) build. 1.0.62: John's 1.0.61 verbs (Konnect parity) brought into the EDA Bridge Standard and the verb battery. Sixteen standard names now answer as aliases of the verbs that do the same job (net_classes, repour, save, update_pcb, annotate, create_symbol, create_footprint, read_symbol, remove_symbol, sch_sheet_symbol, selection, route_pair, fab_check, find_symbol, export_manufacturing, add_rule); a catalog test makes every new verb a standard name, an alias or a reviewed KiCad-only job, and each release now syncs bridge.json, refreshes the standard's KiCad coverage and writes every verb into the README. Fixes: adding items to a board open in KiCad (add_footprint, add_mounting_hole, import_svg, board_outline, update_footprints_from_library) failed as a vague rollback; KiCad 10.0.x (4 and 7 checked) creates nothing from text over its API, so these now refuse with live_create_unsupported and say to close the board, which edits the file; a KiCad lock file left by a KiCad that is no longer running no longer blocks file edits. The verb battery covers all 227 verbs on KiCad 10.0.7, the 78 new ones in project, schematic, library, fab and board scenarios.
1.0.61 (2026-10-27 14:58 UTC)
NATIVE (Rust) build. Every Konnect v0.13.0 capability, 211 verbs (was 133; docs/konnect-gap.md maps all 228 Konnect tools). Schematic: components, pins, items, rotate, region move, annotate, replace and update symbols, field reset, wire delete/split, labels, junctions, net stubs, pin-to-pin wiring, text, buses, atomic batches, sheets and hierarchy, sheet pins, connectivity trace, checks, connectivity fixes, PNG render with visual baselines, design review. Board: outline, layer count, graphics, mounting holes, SVG import, refill, save, add/flip/delete/edit/align footprints, update footprints from library, footprint graphics and 3D models, selection and cross-probe, update PCB from schematic. Routing and rules: modify track, diff pairs, copy routing, netclasses, board rules, custom rules, clearance check, placement score, decoupling placement, fanout plan. Fab: DXF, GenCAD, IPC-2581, ODB++, IPC-D-356, one-zip fab package, fab pre-flight, cost numbers. Projects and libraries: create, info, rename, snapshot; footprint and symbol create, edit, info; library search. PCM: file:// and private wiki repositories, zipPath installs (#132).
1.0.59 (2026-10-26 22:55 UTC)
NATIVE (Rust) build. 1.0.59: the EDA Bridge Standard board model. kicad_routing_state {model:"standard"} answers the standard's board model (mm, y up, custom pads as rectangles with copperPoints, the outline with arcs, unconnected from the copper with isolatedCopper, an order-independent revision), live or from the file; the edit verbs take its revision and, with frame:"standard", its coordinates. New: kicad_layer_stack, kicad_pour_state, kicad_bodies (3D heights from STEP/VRML), kicad_netlist (expect comparison, pin types), kicad_board_summary, kicad_list_nets, kicad_list_designators, kicad_copper_layers, kicad_layers_in_use, kicad_component_data, kicad_component_pins, kicad_sch_no_connect (#131). Fixes: kicad_remove_route honours dryRun (#134); placement outline box follows arcs and circles, ring courtyards no longer collide (#133); PCM libraries resolve ${KICAD10_3RD_PARTY} (#130); the no-ipc build compiles again. Unconnected matches KiCad's DRC on six KiCad 10 demo boards; verb battery on DESKTOP-BAR6S0F (KiCad 10.0.4).
1.0.1 (2026-09-12 13:54 UTC)
NATIVE (Rust) build. 1.0.1: Freerouting on the user's terms. kicad_freerouting {status|install|uninstall} installs Freerouting's own self-contained bundle (88 MB download, 147 MB on disk, its Java runtime inside, nothing installed on the PC, no UAC) only when the user asks, as a background job with progress in status, and removes it on its own. kicad_autoroute {engine: freerouting} writes the Specctra DSN from the board, routes headless with a deadline, and lands the SES copper as native undo steps through the IPC API (or into the closed file with a backup), then DRC. Every autoroute reply names both engines; the AI engine stays the recommendation. Verified on ConfRoomROG: install 6 s, six-net fixture in 3 s, DRC clean, live apply six undo steps, uninstall clean. kicad_uninstall removes the engine too. New kicad-autorouting skill.
1.0.0 (2026-09-12 12:36 UTC)
NATIVE (Rust) build. Native bridge 1.0.0: one Windows executable, no Python or PowerShell, nothing for ab to provision. 96 verbs: everything the Python bridge did plus schematic edit in place (six verbs, ERC-validated), kicad_autoroute (ai engine live), kicad_rescan_libraries verified by loading, kicad_progress and verb_times, a multithreaded server so status and progress polls answer during long verbs, the etiquette loop inside the binary, and the six-beat tour. Live routing on the Rust IPC client with the same revision guard and native undo steps. Gate on ConfRoomROG from this exact zip: 71 pass, 4 fail (three foreground notes from another session's Chrome windows, one cleanup-while-open), 15 skip; kicad_demo passing. In-KiCad Python plugin retired. Known: ab's native recorder drops 4K takes past a minute (adom-bridge#189).
0.9.351 (2026-09-11 11:36 UTC)
Rust port plan phase 0: seeds KiCad's six do_not_show_again nags, api.enable_server, update-check and eeschema prompt suppression at first-run config seeding (bridge-created files only, never a user's own settings); deletes dead launch_editor.ps1, unused handlers/foreground_guard.py and the legacy tour/ orchestrator. Plan and comparison sub-readmes published under docs/. Gate: ConfRoomROG 71 pass / 1 fail (known idle-box foreground grant on kicad_launch) / 15 skip; adom_library_heal verified live.
0.9.350 (2026-09-09 13:49 UTC)
kicad_model_check and model diagnostics on the 3D show verbs (#88)
0.9.350 (2026-09-09): 3D model diagnostics (#88)
- New read-only
kicad_model_check {library, footprintName}or{boardPath}: per (model ...) reference it reports where KiCad would look (project dir, then the 3D search paths; never next to the .kicad_mod), whether the file exists, whether it is a STEP/VRML with geometry, hidden flags and implausible scale, with coded warnings and hints. Footprints that need no body (test points, fiducials, mounting holes, board-only parts) are exempt.renderVerifiedis always false: the viewer frame stays the render proof. kicad_show_3d_chipandkicad_show_3d_board {filePath}attach amodelssummary and a_modelHintwhen a body cannot be there, so a pads-only 3D view arrives with its reason.
0.9.349 (2026-09-09 13:17 UTC)
kicad_status carries operation state for timeout recovery (#87)
0.9.349 (2026-09-09): kicad_status answers "did my operation finish?" (#87)
kicad_statusis the manifest's statusVerb, the verb ab tells a caller to poll after its 130 s budget runs out. It carried plugin inventory only. It now also carriesoperations: every phase in flight (all callers, each frame named), the last finished runs with ok/error and finishedAt, andyoursfiltered to the caller. The run log records the caller and the error text of a failed run so that answer is exact. Plugin liveness is unchanged.
0.9.348 (2026-09-08 20:32 UTC)
Focus guardian identity survives hwnd reuse; editors spawn without activation (pre-promotion run findings)
0.9.348 (2026-09-08): editors launched by open_board/open_schematic start without activation
- The focus guardian's "push a KiCad window behind the user once" now keys on (hwnd, pid) and expires closed windows: Windows recycles hwnd numbers, so a new editor could inherit an already-pushed number and never be pushed at all. The push stays one per window (John's rule). Editors opened by open_board/open_schematic are spawned with SW_SHOWNOACTIVATE like kicad.exe. Measured on an idle ConfRoomROG (no user input for minutes): a new editor still ends on top, because Windows grants a new process the foreground once the foreground lock timeout has expired; with a user active Windows blocks it. Not new behaviour; recorded here so the pre-promotion runner reading is understood.
0.9.347 (2026-09-07 19:10 UTC)
kicad_close honours unsaved work (#84); verified footprint rescan (#51)
0.9.347 (2026-09-07): kicad_close honours unsaved work (#84), footprint rescan verified (#51)
kicad_closeno longer force-kills an editor that is asking "Save changes?": it reports errorCode unsaved_changes with the dialog text and leaves the window open.discardChanges:truepresses Discard for the caller and keeps the close graceful;force:trueis still the only kill. The graceful wait per window is 8 s (was 5 s).kicad_rescan_librariestakes footprints:["Lib:Name", ...] and loads each in the Footprint Editor after the tree refresh, soverifiedis measured (the last one stays shown). Measured on 0.9.343: a footprint installed two hours after pcbnew started loads after the in-place refresh, no restart. The stale-editor wording onkicad_install_footprintnow says that instead of demanding a process restart.
0.9.343 (2026-09-07 18:29 UTC)
Footprint loads with two pcbnew processes; list_footprints reads the fp-lib-table (#81)
0.9.343 (2026-09-07): footprint loads with two pcbnew processes (#81)
- The Library Tree toggle behind every background footprint load asked "the" pcbnew plugin and, with two pcbnew processes alive, got a stray PCB Editor that has no Footprint Editor frame; the tree stayed hidden and the load typed into nothing. It now asks the pcbnew that owns the Footprint Editor.
kicad_list_footprintslists every library in the fp-lib-table with URIs expanded like KiCad does (stock Resistor_SMD and friends included), not only Documents/KiCad//footprints.
0.9.342 (2026-09-07 18:13 UTC)
First-run wizard deadlock: time-boxed dialog clicks and bounded sweeps (#83)
0.9.342 (2026-09-07): first-run wizard deadlock (#83)
- The dialog sweep clicked dialog buttons with a synchronous SendMessage. The first-run "KiCad Setup" wizard opens its "Are you sure?" Confirmation modally inside the Cancel handler, so the click never returned and the only code that would answer the Confirmation was the code waiting on the click. On a truly fresh KiCad (config deleted) that held kicad_open_schematic past ab's 130 s budget. Clicks are now time-boxed (SendMessageTimeout, 1.5 s) and both sweep loops stop after 25 s.
0.9.341 (2026-09-07 18:06 UTC)
Release-day fixes: stock library path resolution (#80), screenshot_all sizeKB (#81), readiness re-detect (#82), routing DRC completeness (PR 82), verified source pushes (#79), full verb-test coverage (#78)
0.9.341 (2026-09-07): release-day fixes from the multi-host verification
- #80:
${KICAD10_SYMBOL_DIR}and the other stock library variables now resolve to the installed KiCad's share directory (per-user installs included) with Configure Paths overrides honoured;kicad_list_symbols {"libraryName":"Device"}works on every box. - #81:
kicad_screenshot_allno longer dies with an internal sizeKB error when a capture reply carries no size. - #82:
kicad_readinessandkicad_list_versionsre-detect when a cached kicad.exe has vanished (KiCad uninstalled while the bridge ran) instead of reporting ready until a bridge restart. - Live routing (PR 82, Codex): DRC snapshots refill zones; capped violation lists are flagged and the
error-delta check refuses to certify a truncated report (
drc_incomplete, no copper changed). - #79: the release tool verifies every source push and refuses to release on a failed chunk.
- #78: the verb test runner ships its rp2040 fixture, learns the Windows user from the box, covers every live verb (tests or a stated skip), pings pcbnew instead of eeschema (no scripting there on KiCad 9/10), and only counts a foreground steal when a user window was actually displaced.
0.9.340 (2026-09-07 16:56 UTC)
Live routing verbs through KiCad's IPC API (routing_state, route_net, remove_route, routing_validate), offline copper verbs (board_pads, add_track, add_via, route), kicad_ipc_api, KiCad 10 name-based nets, vendored routing deps
0.9.340 (2026-09-07): live routing through KiCad's IPC API
- New live copper verbs from the per-net routing branch:
kicad_routing_state,kicad_route_net,kicad_remove_route,kicad_routing_validate. Official KiCad IPC editing (KiCad 10.0.1+ with the IPC API server on), native Undo per call, revision and net guards, snapshot DRC before commit. - Offline file verbs for closed boards:
kicad_board_pads,kicad_add_track,kicad_add_via,kicad_route. kicad_ipc_api: read or flip KiCad's IPC API server switch (needs a KiCad restart).- The board parser reads KiCad 10 name-based nets as well as numbered nets.
- The release zip now vendors the IPC client (
routing_deps/: kicad-python 0.8.0, protobuf, pynng, cffi; Windows wheels for CPython 3.11 to 3.13). Nothing is pip-installed on the desktop. - Not an autorouter and not an electrical sign-off: the caller chooses every waypoint.
- Tour work from 0.9.339 (two-part beats, 98% layout, 3D bodies) is unchanged.
0.9.339 (2026-09-05 19:16 UTC)
Tour motion: zoom depth per beat (one step for a single part, two plus one for a sheet or board)
0.9.338 (2026-09-05 18:55 UTC)
Tour: reopen the board when the file on disk is newer than the running pcbnew, so attached 3D bodies actually show
0.9.337 (2026-09-05 18:50 UTC)
Tour: a 3D model file that is not installed on this box counts as dead too; the MOSFETs then get KiCad's TDSON-8-1 body and the board reloads
0.9.336 (2026-09-05 18:46 UTC)
Tour: dead 3D model references are removed as balanced blocks (the regex missed the MOSFETs), so KiCad's TDSON-8-1 body attaches and the board reloads
0.9.335 (2026-09-05 18:43 UTC)
Tour: 3D body attach report lists what it saw for the MOSFET footprints (debug)
0.9.334 (2026-09-05 18:39 UTC)
Tour: two-part beats (A loads with its own line, B explains and moves once verified), part timestamps on the record, 3D body attach report says where it looked
0.9.333 (2026-09-05 18:36 UTC)
Tour: every beat in two parts (A loads the window with its own line, B starts once verified with the explaining line and the motion); part timestamps on the record; dead 3D bodies replaced by KiCad standard ones
0.9.332 (2026-09-05 18:29 UTC)
Footprint open: a hidden Library Tree filter box counts as missing (wx hides the pane, the control survives), so the pane is shown and waited for; tour prep summary (3D bodies attached, cache restart) on the progress record
0.9.331 (2026-09-05 18:22 UTC)
Footprint open: the plugin-free background loader also shows a hidden Library Tree pane before typing (arav-rog: the pane fix only covered the fallback path); tour reloads the board after attaching 3D bodies; prep summary on the record
0.9.330 (2026-09-05 18:11 UTC)
Tour: attach KiCad's standard 3D bodies to footprints the board left without one (six MOSFETs get TDSON-8-1); Footprint Editor Library Tree pane is shown once and waited for, never toggled back off
0.9.329 (2026-09-05 17:59 UTC)
Tour: restart KiCad during prepare when the footprint file is newer than the running KiCad (process start time vs file mtime), not only when it is new; startedAt and narrationAt on each step record
0.9.328 (2026-09-05 17:52 UTC)
Tour: footprint install leaves an identical file untouched (mtime bump made KiCad's cache look stale on every tour after the first); per-beat startedAt and narrationAt on the record for syncing a recording
0.9.327 (2026-09-05 17:32 UTC)
Tour: editor and viewer windows at 98 percent of the work area, centered (John)
0.9.326 (2026-09-05 17:21 UTC)
Tour: all editor and viewer windows at 95 percent of the work area, centered; 2D motion aims at the featured part (position parsed from the board and schematic) and checks the canvas after each gesture; 3D motion re-frames when the board is clipped or tiny
0.9.325 (2026-09-05 13:35 UTC)
Footprint open: when the Footprint Editor's Library Tree pane is hidden, show it through the frame's own View menu (plugin wm_command) before navigating; arav-rog had it hidden and every load failed
0.9.324 (2026-09-05 13:21 UTC)
Footprint open: never restart KiCad for a stale cache when the editor never opened (plugin_not_running restarted KiCad twice on arav-rog); tour footprint beat ensures pcbnew is open and its plugin alive; window rows carry minimized/image so 'in front' skips minimized windows
0.9.323 (2026-09-05 13:08 UTC)
Tour: a brand-new footprint restarts KiCad during prepare (before any window), never mid-beat; the footprint beat waits retryAfterMs on kicad_restarted_retry
0.9.322 (2026-09-05 13:07 UTC)
Tour: a brand-new footprint restarts KiCad during prepare (before any window), not mid-beat; install_footprint reports existedBefore; the footprint beat waits retryAfterMs on kicad_restarted_retry
0.9.321 (2026-09-05 13:03 UTC)
Tour: 'in front' ignores shell popups, minimized windows and our own overlays (arav-rog measured RustDesk minimized and PopupHost as the top window); footprint beat retries twice without the plugin wait; 2D motion recenters when a pan or zoom empties the canvas
0.9.320 (2026-09-05 12:50 UTC)
Tour: leave KiCad's main window as KiCad opens it; footprint beat waits for the project manager plugin and retries (cold KiCad on arav-rog failed both footprint beats)
0.9.319 (2026-09-05 12:47 UTC)
Tour: read the unwrapped desktop_list_windows payload (verify and foreground worked off a local list with no z-order on arav-rog); beat captions bottom-left clear of the demo panel; small top captions announce each foreground and the acks
0.9.318 (2026-09-04 23:13 UTC)
Wiki #48: the 20 s idle healer measured window reachability against the primary monitor only and pulled windows on a second monitor back to the primary; it now measures against the monitor the window overlaps
0.9.317 (2026-09-04 17:05 UTC)
Tour remote: dashboard presses recorded, acked with a caption, and honoured at the next gesture like panel presses
0.9.316 (2026-09-04 17:02 UTC)
Tour remote: FIFO press queue (no press lost), poll-drained presses recorded, presses on progress
0.9.315 (2026-09-04 16:53 UTC)
Tour remote: prev/next/pause cut the beat in flight at the next gesture; back goes to the beat before the one on screen; presses and acks recorded
0.9.314 (2026-09-04 16:25 UTC)
Tour layout: restore a window's bounds before the tour closes it so KiCad's sticky geometry is never corrupted
0.9.313 (2026-09-04 16:21 UTC)
Tour layout: read the unwrapped desktop_list_monitors payload so windows are placed in their 80 percent slots
0.9.312 (2026-09-04 16:20 UTC)
kicad_demo layoutProbe diagnostic; layout uses the monitor work area
0.9.311 (2026-09-04 16:14 UTC)
Fix: demo.py lacked the json import used by the new window-bounds save/restore (0.9.310 would have silently skipped saving bounds).
0.9.310 (2026-09-04 16:13 UTC)
Tour layout for the recording (John): each beat's window is placed at 80% of the primary screen in its slot (symbol upper-left, footprint nudged, chip 3D upper-right, schematic lower-left nudged, board 2D lower-left, board 3D lower-right) and the KiCad manager is centered at its own size; every bound is saved first and restored at the tour's end, stop, failure, or the next start (leftovers file), so KiCad's sticky sizes end up as the user had them. Every caption's reply is recorded on progress; a press on the remote gets an immediate acknowledgement caption at the top of the screen; the settle check waits up to 8 s for two identical captures instead of sampling once.
0.9.309 (2026-09-04 15:59 UTC)
Tour 3D beats no longer end with Zoom to Fit: in KiCad's 3D viewer that command also resets the orientation, so the board beat ended top-down on John's laptop; the beat now ends on the isometric it built (zoom in/out net to zero, framed at the opening fit).
0.9.308 (2026-09-04 15:59 UTC)
Motion gate: GetForegroundWindow can lag AD's z-order right after a raise, which aborted the symbol beat's motion at its first gesture on John's laptop while AD had already measured the window on top; the gate now waits up to 1.5 s for the OS to agree. Panel record keeps the callback URL across stage-advance shows.
0.9.307 (2026-09-04 15:52 UTC)
Tour verification (John: 'tool your bridge code to definitively know that the correct thing is showing'): every beat now MEASURES, after its raise, that its own window is the top of AD's z-order, that the live title carries the expected document, that the GL canvas is rendered (kicad_ui canvas probe) and that two captures 0.8 s apart are identical (settled). The result rides on the step and on progress as ; motion runs only on a verified window, otherwise the step says exactly which fact failed and which window was actually on top. Zoom discipline: 2D beats start and end on extents with two wheel clicks in and back out; 3D beats zoom one menu step in and out and end on Zoom to Fit while staying isometric.
0.9.306 (2026-09-04 15:46 UTC)
Tour 3D motion is now deterministic: KiCad's own View menu commands (Rotate X/Z by 10 degrees, Zoom In/Out, Zoom to Fit) resolved from the live menu bar and posted as WM_COMMAND, so the isometric and the orbit are the same on every DPI and need no mouse or foreground; mouse drags remain only as the fallback (they flipped the chip viewer and did nothing in the board viewer on 2026-09-03). Each step in the result now carries the window handle and title it drove.
0.9.305 (2026-09-04 15:38 UTC)
Tour window targeting (John's laptop: fourteen KiCad windows from days of demos; the 2D beat showed an empty untitled PCB Editor and the 3D beat the old sample cube): every beat now targets the tour's own document titles (esc-g431 schematic and board, the Adom STM32 symbol, the LQFP footprint), reuses an existing window instead of opening a duplicate, and opens each 3D view from that exact editor (open_3d_viewer accepts pcbHwnd/fpHwnd). The clean slate at start also closes old adom-demo documents and an empty untitled PCB Editor.
0.9.304 (2026-09-04 15:29 UTC)
Tour identity fix (John's dashboard run, 2026-09-03): ab refused the demo panel, every caption, every raise and every window close from the tour thread with 'carries no caller identity' (toast fallback, no captions, nothing in front). Every loopback call the bridge makes now carries identity: the X-Adom-Caller headers of the request being served, or the bridge's own self caller otherwise; the tour thread and ab's callback thread adopt the identity of the request that started the tour. Also: a failed panel show no longer demotes later tours to the toast (per-tour reset, one retry), and every 3D viewer plus the Footprint Editor are closed before the beats so the footprint beat opens a fresh, re-indexed editor.
0.9.303 (2026-09-04 15:15 UTC)
Tour sync: the verb-side control channel (kicad_demo {control}) is cleared at tour start too, so a pause/next/exit queued against a previous tour never steers a new one; completes the stale-press drain of 0.9.302.
0.9.302 (2026-09-04 15:13 UTC)
Tour sync fixes (John's run on 0.9.301): stale panel presses from the previous show are drained before a tour starts (his earlier NEXT presses made the new tour jump to step 3 at once); the narration mute is reset from the call's muted flag at thread start and pushed to the panel on the first show; STOP from the remote sets stopping on progress immediately so the dashboard can close its own pill; progress carries stopping.
0.9.301 (2026-09-04 15:07 UTC)
Taskbar hygiene (John: frozen progress bars on every KiCad window, no Adom badge): the boot sweep that clears leftover bars ran once at +6 s while ab was still restarting and failed silently; it now retries across the first two minutes until a window answers, and a five-minute idle reaper clears progress and badge on every KiCad window whenever the bridge is driving nothing. Filed adom/adom-bridge#138 for a progress TTL on ab's side.
0.9.300 (2026-09-04 15:01 UTC)
Tour 3D motion recalibrated: the orbit drags totalled about a third of the viewer width and turned the board nearly edge-on (KiCad's trackball is roughly 0.1 degree per pixel). Now ~30 degrees of tilt and ~40 of yaw for the isometric, then three gentle orbits with zoom, slower and smoother for the recording.
0.9.299 (2026-09-04 14:54 UTC)
Tour board-in-3D fix: KiCad's 3D viewers are unowned top-level windows, so picking 'the viewer owned by the PCB Editor' never matched and the chip's viewer was never closed (0.9.298 test-box run: board3d failed with the viewer actually open). The beats now take the viewer that APPEARS after their open, the chip's viewer is remembered and closed by handle before the board's opens, with the topmost viewer as fallback.
0.9.298 (2026-09-04 14:51 UTC)
Fix: the 0.9.297 tour job died on a NameError (_EXIT undefined) before its first progress update, so Play the demo showed the dashboard's transport pill and nothing else (John, lost, 2026-09-03). _EXIT is defined and the job's reset sits inside its try so any early failure lands on progress as an error instead of a silent stall.
0.9.297 (2026-09-04 14:08 UTC)
Tour: motion on every beat for the recording (fit, wheel zoom in/out, middle-drag pans in the 2D editors; Home, an isometric left-drag and three orbits with zoom in the 3D viewers), sent only while the beat's window is confirmed in front and aborted at the next gesture on STOP or when the user switches away. The board-in-3D beat now closes the chip's 3D viewer first and picks the viewer owned by the PCB Editor (the last beat was showing the chip's viewer by title match). STOP from the remote's X now clears the caption and ends the tour within the beat, audio already off. Per-beat motion reports ride on the result.
0.9.296 (2026-09-04 14:02 UTC)
Tour foreground fix (John: 'why do I not see you foregrounding any kicad window'): the beat raise called SetForegroundWindow from the bridge process and reported true regardless; Windows refuses that from a background process while the user works elsewhere. The bridge now lifts its no-activate mark, asks ab's desktop_bring_to_front to raise the beat's window once, and reports foregrounded only when the z-order afterwards shows that window on top.
0.9.295 (2026-09-04 13:55 UTC)
The tour now walks a real Adom board, adom/esc-g431 (149 footprints, 227 symbols): its STM32G431 symbol and LQFP-48 footprint are lifted from the wiki files at tour time and installed into the Adom library, then symbol, footprint, chip in 3D, schematic, board 2D, board 3D in that order. Captions were never painting because ab requires reason on desktop_caption; fixed, medium size, one line per beat. Narration re-rendered to match. Wording no longer claims the background: each beat's window is brought to the user once. Dead local 3D model paths in the board are dropped.
0.9.294 (2026-09-04 10:37 UTC)
Demo panel callback URL fix: the bridge read its bound port from a second copy of the server module and sent no eventCallbackUrl to ab (panel presses reached the tour only via poll). The port now travels through the environment, so every press is POSTed to the bridge the instant it is clicked. Verified on the test box: a press to the loopback route paused within the beat, muted at once, and resumed on play.
0.9.293 (2026-09-04 10:34 UTC)
kicad_demo progress now reports panel (last show reply, stage, callback URL), muted, muteSource, lastPress and paused; each step in the final result carries foregrounded (whether the beat's window was brought forward once).
0.9.292 (2026-09-04 10:30 UTC)
Demo panel: reason is sent on every show (ab marks it required on show; a stage-advance show without it was refused live and the remote stayed at 1/7), and every show's reply is recorded on kicad_demo progress (panel: shown, stage, callbackUrl, error) so a refused show is visible instead of silent.
0.9.291 (2026-09-04 10:28 UTC)
kicad_demo adopts the ab 2.1.17 demo-panel contract: the first show passes eventCallbackUrl (loopback POST /demo/event on the bridge's own port) so a press lands the instant it is clicked; mute/unmute silence or replay the beat's narration at once; pause/stop silence at once and apply at the beat boundary; stage-advance shows send only the stage so a user's pause or mute is never undone; the poll stays as backstop and skips presses already delivered. The tour now foregrounds each beat's window exactly once (John: the user must see which window is being demoed, but keeps full control between beats); no persistent focus guardian during the tour. One short ab caption per beat stays.
0.9.290 (2026-09-04 09:32 UTC)
kicad_demo drives ab's desktop_demo_panel (Adom Bridge 2.1.0+, wiki adom/adom-bridge#116): the floaty play/pause/next/back/stop remote is shown at stage 0 with the seven stops, polled between beats, stage and state updated per beat, hidden on done/exit/error; the toast transport remains only as the fallback for an older ab. Every beat paints one short ab caption (KiCad tour n/7: ...) for about the beat's length instead of a paragraph for a minute (John, 2026-09-03).
0.9.289 (2026-09-03 19:26 UTC)
John, 2026-09-03: no caption on a Symbol Editor launch or rescan reopen (the 0.9.285 one was large, shown too long, and wrong on his laptop: it promised 'behind your window' while KiCad raised itself in front while loading). Launch is silent. _foreground now also reports editorInFrontAtEnd, measured from AD's z-order at return time, so a response never claims background about a window the user can see on top. Dev skill records the rule: one early look, no fighting the user for the foreground, captions only on the opt-in allowFocusSteal path and short.
0.9.288 (2026-09-03 19:00 UTC)
Captions before a KiCad window appears now name the calling AI thread (John saw one on his laptop and could not tell which thread was opening the editor). The Symbol Editor close used by rescan goes through ab's desktop_close_window (ab 2.1.12+, graceful, never forced) with the local WM_CLOSE as fallback for older ab; responses say editorCloseVia. Bridge owns KiCad, AD owns Windows (wiki #74 item 3).
0.9.287 (2026-09-03 17:58 UTC)
Wiki #71 (Ray, 0.9.286 run): (1) the posted Enter now goes FIRST to the window holding keyboard focus in KiCad's GUI thread (GetGUIThreadInfo), and wxDataView children count as tree candidates regardless of height, so a short Libraries pane no longer yields zero targets; (2) a navigation that ran out of the call budget returns navigation_unconfirmed_within_budget with the trace and _foreground instead of the 'still coming up' contract about an editor that was already driven; (3) an editor the bridge opened after the library file was last written is never judged stale again, so repeated calls stop re-opening it (staleVeto says so); (4) symbol_editor_did_not_open carries pathwaysTried; navigation_failed responses carry errorCode and resolved fields.
0.9.286 (2026-09-03 17:05 UTC)
Z-order guard fix: the 0.9.285 guard read AD's window list with the wrong envelope shape and always saw nothing (field test reported 'no window was launched' during a real relaunch). Both the Symbol Editor launch guard and handlers/foreground_guard now read z-order through handlers.kicad_windows, the one parser of AD's desktop_list_windows.
0.9.285 (2026-09-03 17:01 UTC)
Foreground etiquette on the Symbol Editor launch (wiki #71 field test): before opening or auto-rescan-relaunching the editor the bridge captions why a KiCad window is about to appear, remembers the user's front window, and the moment the new frame exists looks ONCE at the z-order; if the frame landed above a non-KiCad user window it slides the frame back behind it with SetWindowPos(NOACTIVATE) and then leaves the z-order alone for good (alt-tab and taskbar clicks stay the user's). show_library responses carry _foreground with what happened. kicad_install_symbol success now includes kicadParser (KiCad's verdict on the written file).
0.9.284 (2026-09-03 16:44 UTC)
kicad_set_design_rules: response separates fabRuleViolations (DRC items citing one of the fab's rules by name) from otherViolations, and carries drcSummary; the copper layer count is read per layer entry, not per line, so a one-line (layers ...) block no longer infers 1 layer.
0.9.283 (2026-09-03 16:38 UTC)
Wiki #73: kicad_list_design_rules and kicad_set_design_rules consume adom/pcb-design-rules at call time (fab, layers, process; layers defaults to the board's copper count; stages .kicad_dru with backup; runs DRC with it). Wiki #62: kicad_list_symbols (bridge inventory + kicadParser), and kicad_show_library resolves an MPN/file name to the real symbol name (exact, case-insensitive, unique prefix) reporting aliasedFrom/aliasHow. Navigation trace no longer implies the filter was not applied when wx answers WM_GETTEXT with ''. kicad-bridge-dev skill records the #71 lessons.
0.9.282 (2026-09-03 16:25 UTC)
Wiki #71 (Ray's remaining case): on a fresh Symbol Editor the filtered tree lists the symbol but nothing is selected, so the posted Enter has nothing to activate and the posted double-click depends on row geometry (DPI). Ray measured select-then-real-Enter loads it. show_library now adds keyboard-only rounds: Down x1..3 posted to the tree candidates, then Enter, title-verified, still PostMessage only (no focus, no foreground). Success responses carry the navigation trace too, so a re-run shows which round landed.
0.9.281 (2026-09-03 16:19 UTC)
Wiki #71: kicad_show_library failure responses now carry a per-step navigation trace (search Edit found, parent chain, filter text as read back, tree candidates with class and rect, editor title after Down, after posted Enter, after posted double-click). Ray measured on his box that the tree lists the symbol and a real Enter loads it while the bridge's posted Enter and double-click do not; the trace is how the next build finds which hwnd the Enter must reach.
0.9.280 (2026-09-03 16:00 UTC)
kicad_install_symbol now passes errorCode (kicad_refuses_symbol), kicadParser and _hint through to the caller; 0.9.279 set them inside add_symbol but the verb wrapper dropped them, so the wire response had errorCode null.
0.9.279 (2026-09-03 15:57 UTC)
Wiki #71 second cause, measured on ConfRoomROG with KiCad's own parser: one malformed symbol makes KiCad refuse a whole .kicad_sym (Symbol Editor lists the library EMPTY) while the bridge's structural reader called it clean. New handlers/kicad_parse_check.py runs kicad-cli sym export svg (read-only) as KiCad's verdict and inventory. kicad_install_symbol and kicad_install_library refuse a file KiCad refuses before writing (kicad_refuses_symbol / kicad_refuses_library); kicad_adom_library_status, kicad_lint_library and the kicad_show_library error carry kicadParser; kicad_adom_library_heal mode:prune drops the symbols KiCad refuses (dryRun names them, original kept as .pruned.bak). Lint's checkmark now says whether KiCad was consulted. Also measured: KiCad's library index is process-wide; a reopened editor frame keeps the old symbol set until kicad.exe fully restarts.
0.9.278 (2026-09-03 11:49 UTC)
Wiki #72: kicad_install_library handed a single-part .kicad_sym now returns singlePartFile:true plus a hint naming kicad_install_symbol {filePath}, on both the fresh and already-registered success paths; a real multi-symbol library gets no hint. The verb still does what it did (registers the file as its own library); it just stops being silent about the shared Adom library being untouched.
0.9.277 (2026-09-03 02:41 UTC)
kicad_adom_library_status: orphanedLibrary now means the orphan holds symbols the registered file lacks (unique-name compare; new orphanMissingFromRegistered and orphanMissingSample). A count compare kept flagging John's orphan after the 0.9.276 merge because its 122 lenient count included 28 duplicate copies. build_release.py refuses a non-semver first argument (a stray flag was once stamped in as the version).
0.9.276 (2026-09-03 02:35 UTC)
heal merge reads a corrupt orphan tolerantly: the orphaned Adom library on a redirected box had 94 symbols inside the library plus 28 duplicate copies appended AFTER the closing paren (the old appender bug's fingerprint), so the strict gate refused the whole file. The heal SOURCE is now read block by block with a quote-aware depth scan, each block balance-checked on its own, duplicates deduped first-copy-wins and reported; the file WRITTEN still goes through the strict gate. Measured on the real file: 94 unique recoverable, 0 unparseable, 28 dupes.
0.9.275 (2026-09-03 02:32 UTC)
kicad_adom_library_heal (wiki #71 follow-up, John's call: merge): reconcile a split Adom library by merging every symbol from the orphaned bridge-default file into the registered file KiCad reads, one quote-aware add behind the balance gate with a .bak; dryRun previews; repoint mode kept as the other answer. Never runs on its own. Idempotent, refuses an unbalanced source, never edits or deletes the orphan.
0.9.274 (2026-09-03 02:06 UTC)
Wiki #71 root cause: on a OneDrive-redirected Documents the bridge used %USERPROFILE%/Documents while KiCad resolves the shell Documents folder, so the bridge wrote and reported symbols in a file KiCad never reads. Fix: kicad_detect resolves user_dir like KiCad (handlers/win_paths), the Adom symbol and footprint libraries are ROW-FIRST (install writes to the file sym-/fp-lib-table registers), adom_library_status reports registeredPath/bridgeDefaultPath/split/orphanedLibrary, and the library_cache_stale verdict is built from that measurement instead of a cache story (both prior explanations were disproved by Ray).
0.9.273 (2026-09-03 01:15 UTC)
Adopt the insiders tier: bridge.json declares insidersManifestUrl, build_release ships to insiders by default and refuses to publish without a changelog, tools/promote.py moves the public manifest only on a human's attestation. Wiki #72 groundwork.
0.9.272 (2026-09-02, backfilled)
Wiki #71 (Ray): stop asserting causes the bridge never checked. show_library's library_cache_stale message claimed the editor indexed before the symbol was added, which Ray's ordering disproved; it now describes KiCad's PROCESS-WIDE library cache. The starting contract no longer reports "still coming up" when no Symbol Editor window exists at all (it reported progress for 12 minutes on a window that was never created). kicad_rescan_libraries' tree-refresh path no longer claims parts "are now visible" - an effect it never verified - and returns verified:false.
0.9.271 (2026-09-02, backfilled)
handlers/kicad_windows.py: ONE KiCad window finder replacing six per-module EnumWindows loops, AD's desktop_list_windows first (carries z-order) with local enumeration as fallback, 0.25s TTL because a bridge calling AD is re-entrant. kicad_errors migrated onto it, so dialogs are matched by OWNING EXE instead of by title. find_project_manager de-duplicated from the two editor modules.
0.9.270 (2026-09-02, backfilled)
kicad_screenshot_all captures via AD desktop_screenshot_window (owned popups, coordMap, auto-pull) with the local PrintWindow kept as fallback; _canvas_probe stays local because blank-GL-canvas detection needs raw BGRA. kicad_errors reads TaskDialog text through AD UIA at DISCOVERY time - the previous two-step hand-off raced and lost the message.
0.9.269 (2026-09-02, backfilled)
Documented the three error channels (dialogs, captured stderr, screenshots) and kept the screenshot loop as the deliberate floor under the other two.
0.9.268 (2026-09-02, backfilled)
kicad_errors handles Windows TaskDialogs, whose DirectUI text win32 cannot read.
0.9.267 (2026-09-02, backfilled)
kicad_errors: enumerate KiCad error/warning dialogs read-only. KiCad writes no log file and in GUI mode wxLogError becomes a message box, so the dialogs are where a failure reason actually lives.
0.9.266 (2026-09-02, backfilled)
Capture KiCad's stderr instead of discarding it (launch used stdout/stderr=DEVNULL) plus KICAD_ENABLE_WXTRACE, and add kicad_log_tail with a byte offset.
0.9.265 (2026-09-02, backfilled)
handlers/foreground_guard.py: caption before any action known to foreground, and a z-order guard with ONE look inside 200ms, then hands off permanently so a user alt-tabbing to KiCad is never fought.
0.9.264 (2026-09-01, backfilled)
PCM verbs resolve KICAD_3RD_PARTY the way KiCad does, via the Windows shell Documents folder - with OneDrive Known Folder Redirection that is %USERPROFILE%/OneDrive/Documents, and installing to the wrong one made PCM report a package installed while no library ever appeared.
0.9.263 (2026-09-01, backfilled)
kicad_pcm_install / pcm_list / pcm_uninstall: install a package from a KiCad PCM repository on disk exactly as the Plugin and Content Manager does, so KiCad's own dialog lists the result as Installed and registers the library tables itself.
0.9.262 (2026-09-01, backfilled)
Netlist and connectivity family: kicad_extract_netlist, trace_net, find_connections, analyze_connections. Read-only via headless kicad-cli, so they work with KiCad closed. Closes the largest gap against third-party KiCad MCP servers, seven of eight of which had netlist tooling this bridge lacked.
0.9.261 (2026-09-01, backfilled)
Three-way merge recovering fixes that 0.9.251-0.9.260 had silently reverted (the quote-aware .kicad_sym parser, demo captions, the #54 sub-node verify) while keeping Colby's 0.9.251-0.9.260 work intact. Root cause fixed too: build_release.py pushed only BRIDGE_VERSION/bridge.json/manifest, never the source it shipped, so the release zip and the page repo disagreed and the next person to publish from the repo reverted everything.
# kicad-bridge release notes
Newest first. Written at publish time by tools/build_release.py, which refuses to
publish without one.
**Backfilled below 0.9.273 (2026-09-02).** Releases 0.9.261-0.9.272 shipped with
no usable changelog: build_release.py never passed `--changelog`, so the server
synthesised "- Update N file(s)" from repo-push commits that were themselves
unnamed. These entries were reconstructed after the fact from the work they
contain, which is exactly the situation the mandatory-notes gate now prevents.
Treat them as accurate but secondhand.
## 1.0.107 (2026-11-08 18:17 UTC)
NATIVE (Rust) build. kicad_move_footprint refuses an argument it does not read (errorCode unknown_argument, nothing moved), so a misspelling such as rot for rotation no longer moves a part without turning it; suggestedKey names the right key (contributed by Josh Aberdeen, PR #70). The call's reason and caller, the bridge's own keys and kicad_align_parts's arguments are still accepted.
## 1.0.106 (2026-11-08 13:33 UTC)
NATIVE (Rust) build. kicad_silk_text_batch, kicad_silk_fields_batch and kicad_silk_graphics_batch take frame:"standard", so the y-up positions kicad_silk_state reports by default go back unchanged (wiki #141). kicad_silk_text_batch refuses a text placed outside the board outline with errorCode text_off_board, and says when a negative y looks like a y-up position sent without frame:"standard"; allowOffBoard:true lets it through. kicad_silk_state's reply says which frame its positions are in and how to send them back.
## 1.0.105 (2026-11-06 21:20 UTC)
NATIVE (Rust) build. Live routing and edit verbs (kicad_route_net and the others that compare DRC before and after) no longer refuse with drc_incomplete when only warning types, such as silk_overlap or silk_over_copper on a dense board, reach KiCad's 199-per-type report cap (wiki #140). An error type at its cap still refuses, and the refusal now names it in cappedErrorTypes. violationReportMayBeTruncated is still reported for information.
## 1.0.104 (2026-11-05 19:07 UTC)
NATIVE (Rust) build. kicad_close_all_documents and kicad_close no longer close a board or schematic another AI thread opened or used (wiki #139). Such a document stays open with keptOpen why "opened by <thread>"; kicad_close refuses with errorCode documents_in_use and closes nothing. force:true with a reason closes past it. kicad_close_document {path} closes your own board as before.
## 1.0.103 (2026-11-05 16:11 UTC)
NATIVE (Rust) build. kicad_pcm_install and kicad_pcm_uninstall refuse a package identifier that is a path (errorCode invalid_identifier). Before this, an identifier holding a full folder path, including one set by a package zip's metadata.json, deleted that folder.
## 1.0.102 (2026-11-05 01:29 UTC)
NATIVE (Rust) build. 1.0.102: kicad_show_library with only a library name now just shows the library.
- **Fix, parts walked:** with no part named, kicad_show_library set the filter and then kept trying to load one, clicking through the library's parts row by row and leaving the last one on the canvas. It now stops once the filter is set, for symbols and footprints. Calls that name a part are unchanged.
- **Fix, parts listed:** the tree now lists every part of the library and nothing from other libraries. The filter was a text search on the name, which left out parts that didn't mention it and could pull in other libraries' parts that did.
- **The reply says what the canvas shows:** a warm editor keeps the part it already had, so canvasPart names it and canvasFromOtherLibrary says if it came from another library. A proof image shows that part until one is loaded.
- **Fix, empty editors:** a capture of an editor with no part loaded no longer waits for a canvas that will never paint, and says canvasExpectedEmpty instead of warning that the canvas is blank. That takes about 20 seconds off these calls.
- **Behaviour change:** if the filter can't be set, the reply is now success:false with library_filter_failed. It used to say success with the library shown.
Tested on KiCad 10.0.8 (battery 3/0/1 pass/fail/skip on DESKTOP-BAR6S0F).
## 1.0.101 (2026-11-05 01:16 UTC)
NATIVE (Rust) build. 1.0.101: kicad_show_library with only a library name now just shows the library.
- **Fix, parts walked:** with no part named, kicad_show_library set the filter and then kept trying to load one, clicking through the library's parts row by row and leaving the last one on the canvas. It now stops once the filter is set, for symbols and footprints. Calls that name a part are unchanged.
- **Fix, parts listed:** the tree now lists every part of the library and nothing from other libraries. The filter was a text search on the name, which left out parts that didn't mention it and could pull in other libraries' parts that did.
- **The reply says what the canvas shows:** a warm editor keeps the part it already had, so canvasPart names it and canvasFromOtherLibrary says if it came from another library. A proof image shows that part until one is loaded.
- **Behaviour change:** if the filter can't be set, the reply is now success:false with library_filter_failed. It used to say success with the library shown.
Tested on KiCad 10.0.8 (battery 3/0/1 pass/fail/skip on DESKTOP-BAR6S0F).
## 1.0.100 (2026-11-02 22:25 UTC)
NATIVE (Rust) build. 1.0.100: kicad_update_pcb sets every new part's reference, whichever way its library wrote it (#138), and the verbs ruled on standard #29.
- **#138 fixed:** new parts could keep their library's REF** placeholder and read as missing, because the verb only recognised KiCad's own spacing of the reference. It now handles any spacing or line breaks, bare words and the older fp_text form, and adds the field if the footprint has none. The value is set the same way.
- **New refusal:** a part that still doesn't read back with its reference now stops the update with reference_not_set and names the footprint, instead of being written to the board.
- **Boards already updated:** a board that already has REF** parts isn't repaired by running the update again. Start from the empty board, or set those references from the matching symbols.
- **New verbs:**
- **kicad_place_parts:** footprints from a library onto a board, with position, rotation and side, read back. Each part is its own Undo step.
- **kicad_edit_tracks:** width, layer and ends of given tracks, as one Undo step.
- **kicad_extensions:** list, install or remove plugins through KiCad's Plugin and Content Manager.
- **kicad_preferences:** read KiCad's settings by dotted path, or change them. set is refused with reason:"tool_running" while KiCad runs.
- **kicad_cancel_run:** stops a background Freerouting job. Nothing from that run reaches the board.
- **kicad_physical_properties:** answers not_supported, because KiCad has no materials or masses on a part.
- **Standard's shape on existing verbs:**
- kicad_sch_label, kicad_sch_no_connect and kicad_sch_wire take sheet and id. kicad_sch_label takes remove:true.
- kicad_select_items takes clear and where, and names each designator it couldn't select in failed. where:"sheet" is refused, because the Schematic Editor has no API. Changed: one unknown designator no longer refuses the whole list.
- kicad_model_check adds parts and checked, with found and hasGeometry per model.
Tested on KiCad 10.0.8 (battery 376/0/1 pass/fail/skip on DESKTOP-BAR6S0F).
## 1.0.99 (2026-11-02 21:18 UTC)
NATIVE (Rust) build. 1.0.99: fourteen more of the standard's verbs under their own names, and update_pcb and teardrops in the standard's shape.
- **kicad_read_board:** the whole board in one read: components, nets, layers, copper, rules, occupancy, outline. sections picks some, limit caps each list and truncated names the capped ones.
- **kicad_read_schematic and kicad_schematic_data:** one sheet, for filePath or the sheet open in the Schematic Editor.
- Positions are mils from the sheet's lower-left grid point, y up.
- schematic_data adds each pin's number, name, electrical ordinal (with KiCad's own type name beside it), position, orientation and length.
- **kicad_pcb_report:** numbers instead of pixels, for a board, a .pretty library or one .kicad_mod.
- **kicad_instances:** every running KiCad process.
- **kicad_check_dialogs:** every open dialog with its buttons, category, safe action, meaning and a screenshot. It answers nothing.
- **kicad_save:** saves a board through KiCad's API and a schematic through the Schematic Editor's File > Save, so schematics can now be saved. It replaces the alias to kicad_save_board, which stays as it was.
- **kicad_close_document:** closes one board or schematic by path and never saves. Unsaved edits are discarded, as the standard says.
- **kicad_close_all_documents:** closes every editor. Unsaved work stays open and is listed unless save or discardUnsaved says otherwise. KiCad's project manager stays up.
- **kicad_ensure_licensed, kicad_signin_status, kicad_setup_trial:** the standard's onboarding answers. KiCad needs no licence or account, and ensure_licensed starts it if it is not running.
- **kicad_set_models and kicad_add_models:** a library symbol's footprint link, filters, parameters, comment and description. KiCad has one Footprint field, so add_models puts further footprints in the symbol's footprint filters.
- **kicad_update_pcb (kicad_update_pcb_from_schematic):** takes execute, allowRemovals and keepBoardOnly, and projectPath alone names the board. The reply adds preview, changeOrder, executed, afterExecute, board, dialogs and steps. execute:true refuses while removeParts is not empty unless allowRemovals or keepBoardOnly says what to do. apply:true is unchanged. A board open in KiCad is still refused: use KiCad's own Update PCB from Schematic there.
- **kicad_teardrops takes the standard's arguments and defaults:**
- Behaviour changes: Track to track is now on by default, and the board is now saved by default (save:false leaves it unsaved).
- tracks and tJunctions both answer KiCad's one Track to track box. vias also covers through-hole pads unless pthPads says otherwise.
- filePath is optional. force:true is refused, because KiCad has no such mode.
- The reply adds teardropsBefore, teardropsAfter, steps and dialogsLeft.
Tested on KiCad 10.0.8 (battery 370/0/1 pass/fail/skip on DESKTOP-BAR6S0F).
## 1.0.98 (2026-10-31 17:28 UTC)
NATIVE (Rust) build. 1.0.98: the standard's document_info.
- **kicad_document_info:** the active KiCad document, meaning the topmost KiCad window. It reports:
- name and kind: board, schematic, library, project or model;
- modified: the leading * KiCad puts in the title;
- saved, path, project, and the sub-sheet when a schematic shows one.
- version is null, because KiCad keeps no versions.
- Read only: it opens nothing.
- **Where the path comes from:**
1. the editor's own command line, read through Adom Bridge's process list;
2. the project folder, for an editor opened inside the project manager;
3. KiCad's recent-file list, as a last resort.
pathFrom says which. windows[] lists every KiCad window, topmost first.
- Checked live on KiCad 10.0.8: with the rp2040 project's project manager, PCB editor and schematic open, it named the schematic (topmost) with its path from the command line and the project beside it.
Tested on KiCad 10.0.8 (battery 356/0/1 pass/fail/skip on DESKTOP-BAR6S0F).
## 1.0.97 (2026-10-31 17:02 UTC)
NATIVE (Rust) build. 1.0.97: tested on KiCad 10.0.8, and every build now records the KiCad its battery ran on.
- **KiCad 10.0.8:** the test laptop was updated from 10.0.7 through the bridge's own kicad_tool_update apply (the official installer, per user, no UAC). This build's full battery ran on 10.0.8.
- **Release records the tested KiCad:** build_native_release.py --battery <report> refuses a failed, partial or foreground-grabbing run, and refuses a run that tested another bridge version. Otherwise it writes the result:
- into the manifest as testedWith {kicad, battery, target, at}, which carries to public on promotion;
- into the release notes.
- **kicad_readiness:** testedKicad is the KiCad this build's battery passed on (null in a dev build). newerThanTested is true when the installed KiCad is newer.
- The battery report records the KiCad and bridge it tested (report.json "tested", and the report's heading).
Tested on KiCad 10.0.8 (battery 355/0/1 pass/fail/skip on DESKTOP-BAR6S0F).
## 1.0.96 (2026-10-30 23:02 UTC)
NATIVE (Rust) build. 1.0.96: three more standard verbs answered fully: net_connections, remove_items and doc_params (standard 0.30.4).
- **kicad_net_connections:** every pad with its net and owner (U1.3) in mils. Per net it gives the span and the airline length: the minimum spanning tree over its pads, the shortest copper a router could need.
- **kicad_remove_items:** deletes free tracks, arcs and vias given by their geometry, exactly as kicad_routing_state reported them (the standard's y-up frame; frame:"kicad" for KiCad's own).
- One result per item: ok, or err:not found.
- An open board takes it as one Undo step; a closed board is written with a backup.
- expectedRevision is optional, and the live edit still refuses a board that changed while it was prepared.
- **kicad_doc_params:** parameters KiCad's title block has no field for (DrawnBy, DocumentNumber, ...) are now kept as the project's text variables, which the title block and any text show as ${Name}. The reply lists them all as params, with the standard's set and saved. Before, those parameters were reported as notStored.
## 1.0.95 (2026-10-30 21:41 UTC)
NATIVE (Rust) build. 1.0.95: the standard's cross_check from its engine, eleven verbs that were partial under other names, now under their own, and KiCad found on any drive (engine 0.24.0, standard 0.30.0).
- **kicad_cross_check:** compares the schematic's designators with the board's, computed by the standard's engine.
- The reply gives matched, onSheetNotOnBoard and onBoardNotOnSheet.
- The sheets are read through KiCad's own netlist of the whole hierarchy. The board is read from the open PCB editor when it serves the board, otherwise from the file.
- sameProject (with a _warning) says when the sheet and the board sit in different folders.
- Checked: on a copy of the rp2040 project with C1 deleted from the board, cross_check names C1 as on the sheet but not the board, and the matched count drops by one.
- **kicad_list_library:** the symbols in a .kicad_sym or the footprints in a .pretty folder, the kind taken from the path (data.names, data.count).
- **kicad_open_document, kicad_open_project, kicad_activate_document:** open or bring up a board, schematic or project by path in the background. A board opened this way is the one the PCB editor's API serves.
- **kicad_render_board_layers:** board layers rendered to PNG or SVG through kicad-cli without a window.
- Fourteen presets (copper, silkscreen, mask and paste of either side, outline, drill at real size, assembly, fabrication), or a layer list.
- Bottom views are mirrored so they read from below, and dpi is honoured.
- **kicad_export_bom:** the project's BOM CSV from its root schematic, with files and outputDir.
- **Fixed: KiCad installed on a drive other than C: is found (wiki #137).** The bridge searches in this order:
1. KiCad's registry key;
2. KiCad's uninstall entries;
3. Program Files\KiCad, Program Files (x86)\KiCad and \KiCad on every fixed drive;
4. kicad-cli on PATH.
- bridge.json's detect globs include D: to G:, so Adom Bridge's host-app check sees such an install too.
- Library paths were already built from the detected root.
- The skill now says never to install KiCad in the Linux workspace: the bridge runs the user's own kicad-cli.
- **kicad_routing_drc:** KiCad's DRC on the board as the PCB editor holds it (unsaved edits included), with the project's rules and zones refilled. The reply is clean, errors, unconnected and violations[{rule, severity, description, at}].
- **kicad_set_track_width:** sets the width of the existing tracks and arcs on nets or a net class, optionally on one layer (top, bottom, mid N). An open board takes it as one Undo step through kicad_modify_track; a closed board is written with a backup. The reply gives byNet and drcAfter.
- **kicad_footprint_primitives:** one placed part's lines, arcs, pads (size, hole, net, solder and paste mask expansion in µm) and texts, in mils on the board, with other kinds counted.
- **kicad_rules_by_kind:** every rule the board answers to, grouped by kind and sorted by KiCad's precedence: custom .kicad_dru rules, then net classes, then Board Setup minimums.
- Engine adom-eda-checks 0.24.0 vendored unchanged (standard 0.30.0). kicad_bom stays KiCad's own: it was already exact.
## 1.0.94 (2026-10-30 20:46 UTC)
NATIVE (Rust) build. 1.0.94: the standard's export_3d, import_design, edit_pours, tool_update and import_step, and its schematic part verbs in their own arguments (standard 0.29.5).
- **kicad_export_3d:** writes the board's 3D model through kicad-cli in stl, glb, vrml, ply, brep, xao, u3d, stpz or 3dpdf.
- components:false exports the bare board. copper, silkscreen and soldermask add those layers.
- obj, 3mf, iges and other formats KiCad can't write are refused by name (not_supported), with what to use instead.
- **kicad_import_design:** brings an EAGLE, Altium, PADS, CADSTAR, Fabmaster, P-CAD or SolidWorks PCB board into a new KiCad project through kicad-cli's importer. The reply counts the parts and nets and gives the importer's warnings.
- kicad-cli imports the board only, and the reply says so (schematicImported: false). The schematic comes in through KiCad's File > Import > Non-KiCad Project.
- Formats KiCad has no importer for, such as OrCAD, are refused by name.
- **kicad_edit_pours:** changes existing pours in place: clearance, minimum width, thermal reliefs (on/off, spoke, gap) or the pad connection, priority, net, and whether islands are kept. Each pour comes back with its settings before and after.
- A closed board is written (a .adom-bak is kept) and refilled by kicad-cli, and pourState is the copper after the refill.
- On a board open in the PCB editor, each zone KiCad holds is updated in place through its API (UpdateItems: id, outline and every other setting kept) as one Undo step. The board is then refilled, and the settings are read back from KiCad (verified).
- expectedRevision is optional, and KiCad's revision or pour_state's are both accepted.
- **kicad_pour_state:** each pour now carries its id (the zone's uuid), which kicad_edit_pours takes.
- **kicad_sch_place_part, kicad_sch_connect, kicad_sch_edit, kicad_sch_swap_part:** the standard's schematic part verbs, under their own names and with their own arguments. They work alone and as kicad_sch_batch ops, and KiCad's own arguments still work too.
- Arguments: positions in mil from the grid point at the sheet's lower-left corner (y up, landing on KiCad's 50 mil grid), parts by designator, and a library as a .kicad_sym path or a table nickname plus the symbol's name.
- sch_connect takes connections [{designator, pin, net, kind: label|power|wire|noerc|port}]. sch_edit takes edits [{designator, action: move|moveBy|rotate|designator|comment|delete}].
- Each list is one write, all or nothing. The reply is in the standard's terms: connected/applied, failed, results, atMil, endMil.
- sch_swap_part wires each pin the new symbol puts somewhere else back to where the old pin ended (pinsJoined).
- **kicad_sch_connect_to_net:** kind "wire" draws the stub alone, with no label.
- **kicad_sch_replace_symbol:** joinMoved:true rejoins moved pins.
- **kicad_tool_update:** the standard's tool_update.
- check compares the installed KiCad with the latest stable (current, offered).
- apply installs the offered version with the official installer, per user with no UAC. It refuses while KiCad is open and lists the open documents, unsaved ones marked.
- auto reads or sets KiCad's own update check.
- **kicad_import_step:** answers not_supported with the reason: KiCad places 3D models only as a footprint's own model. It suggests kicad_add_body or kicad_export_step instead.
## 1.0.93 (2026-10-30 19:47 UTC)
NATIVE (Rust) build. 1.0.93: kicad_schematic_review checks the drawing too (engine 0.23.0, standard 0.28.0).
- **kicad_schematic_review:** sends the engine each sheet's drawing (sheetDrawing): wires, buses, junctions, no-connects, labels, pins and symbol boxes. The engine's drawing checks (dangling wires, floating labels, overlapping symbols, ...) now run on KiCad schematics, and the reply says drawingChecked.
- Power symbols that name a net count as power labels. Sheet pins count as hierarchical labels.
- netlist.names lists every label and port name joined into one net, so the engine can flag two names on one net.
- Checked on three real designs, where the engine agrees with KiCad's own kicad_sch_check:
- pic_programmer: one real overlap (R10 drawn over U4) and one info.
- StickHub: one info (no bulk capacitor on a rail).
- The rp2040 sample: the same 10 overlapping-symbol pairs.
- **Fixed: PWR_FLAG no longer joins nets.** A PWR_FLAG was read as a power symbol naming the net "PWR_FLAG", so every net carrying one became one net. This raised a false shorted_nets on pic_programmer and StickHub. Only power symbols whose pin is a power input name a net now.
- **Fixed: escaped label names.** KiCad writes a / in a label as {slash} (and : as {colon}, and so on) in some files. kicad_sch_check and kicad_schematic_review compared the raw text, so the labels VPP/MCLR and VPP{slash}MCLR split one net in two (a false "reaches only R18.2" on pic_programmer). Names are now read as KiCad compares them.
- Engine adom-eda-checks 0.23.0 vendored unchanged (standard 0.28.0).
## 1.0.92 (2026-10-30 19:04 UTC)
NATIVE (Rust) build. 1.0.92: the standard's sch_batch and log_tail shapes (#29).
- **kicad_sch_batch:** ops can be named by the standard's schematic verbs (sch_place_part, sch_connect, sch_edit, sch_swap_part, sch_text, sch_junction, ...) as well as KiCad's own (place_symbol, wire, ...), mixed in one batch.
- sch_connect and sch_edit run as the KiCad verb their arguments call for (wire, label, connect_to_net, no_connect; move, rotate, delete, set_property).
- sch_place_part, sch_connect, sch_edit and sch_swap_part take KiCad's arguments.
- The reply names ercBefore and ercAfter. Any op that fails, an unknown one included, is named by failedOp, and nothing is written.
- Checked: sch_place_part, sch_text, place_symbol and sch_edit ran in one write on a copy of the inverting amplifier sheet.
- **kicad_log_tail:** answers the standard's entries [{level, text}] and next beside lines and nextOffset.
## 1.0.91 (2026-10-30 18:31 UTC)
NATIVE (Rust) build. 1.0.91: three of the standard's library verbs that 1.0.90 refused are now real (#29).
- **kicad_cleanup_libs (the standard's cleanup_libs):** a symbol or footprint library's parts that no given project uses, and parts that repeat another part under a different name (same pins and graphics, or same pads).
- A plan by default. apply with remove takes out only the names listed, which must be in the plan unless force.
- A symbol library keeps a .bak; a footprint file moves to <Lib>.pretty.removed, so both can be put back.
- A symbol another symbol extends counts as used.
- **kicad_build_symbol_modes (the standard's build_symbol_modes):** gives a symbol its De Morgan alternate body, KiCad's second display mode.
- The alternate drawing (rectangle, polyline, circle, arc) goes into every unit, with the standard body's pins copied and any pin shapes changed (inverted inputs). The symbol is marked as having two body styles.
- Checked: KiCad plots the alternate as mode 1 (kicad_symbol_mode).
- **kicad_add_symbol_art (the standard's add_symbol_art):** draws artwork inside a symbol's body rectangle, scaled to fit with a margin and centred, keeping its aspect.
- The art is given as polylines, or taken from another symbol's polylines (adom-symbol's baked chip outline).
- Checked: KiCad plots the art inside the body, with the pins untouched.
## 1.0.90 (2026-10-30 18:00 UTC)
NATIVE (Rust) build. 1.0.90: four more of the standard's verbs (#29: every standard verb answered on every bridge).
- **kicad_swap_footprint (new; the standard's swap_footprint):** puts another library footprint on one placed part.
- The part keeps its position, rotation, side, reference, fields, schematic link, DNP/BOM flags and lock.
- Pads keep their nets by number, and assigns ("9=GND") sets nets on any pad. The reply lists the pads whose net was kept and any pad left without a net.
- Checked: C1 on a copy of KiCad's pic_programmer demo went from an axial to a radial capacitor with both nets kept, and KiCad's DRC is clean.
- **kicad_plate_vias (new; the standard's plate_vias):** in a footprint library, every drilled pad becomes a plated hole through every copper layer when it isn't one already: a thru_hole pad on only some copper layers, or an smd pad with a drill (thermal vias written as surface pads).
- Numbered unplated holes are listed, and plated only with includeNpth. Running it again changes nothing.
- **kicad_normalize_bodies (new; the standard's normalize_bodies):** moves a footprint's 3D model onto its pad cluster (by its offset) when the body sits more than minShiftMm from the pads' centre. Models already on their pads are left alone.
- Checked: a SOIC-8 whose STEP sat 50 mm away was moved back onto its pads.
- **kicad_symbol_mode (new; the standard's symbol_mode):** one body style of a library symbol as a picture, plotted by KiCad: mode 0 the standard body, mode 1 the De Morgan alternate, per unit.
- Checked: 74LS00 in mode 1 shows the OR body with inverted inputs. A symbol with no De Morgan body refuses mode 1.
- The standard's Altium-only verbs (licence, sign-in, agent, extension, symbol-mode specs, cleanup) are now answered in KiCad's equivalents: mapped where KiCad has the job, otherwise unsupported with the reason. panel maps to kicad_send_key's View > Panels toggle; activate_document maps to kicad_open_board and kicad_open_schematic.
- **The standard's Altium-only verbs now exist in KiCad and refuse with not_supported**, each with the reason and what to call instead. They are add_symbol_art, cleanup_libs, build_symbol_modes, license, signin, connect_workspace, agent_start/stop/status/recover, selftest_script_error, extension_ping, install_extension and install_receipt.
- An AI that calls kicad_license learns that KiCad is GPL with no licence page (instead: kicad_license_status) rather than meeting unknown_verb.
## 1.0.89 (2026-10-30 17:18 UTC)
NATIVE (Rust) build. 1.0.89: camera choreography (the standard's animate_view).
- **kicad_animate_view (new; the standard's animate_view):** camera steps run inside the bridge, so the timing is tight enough to narrate over. Everything runs in the background.
- On the PCB editor: zoom_all, zoom_in and zoom_out, as KiCad's own actions through its API.
- In the 3D Viewer: views, orbits, rolls, pans, flip and rotate90, as its View-menu commands.
- view_3d and view_2d switch between them within one call.
- Presets: punch_in, orbit, showcase3d, flip and finale.
- Steps KiCad has no command for (isometric, ortho) are listed in skipped, never faked. The schematic lane is refused as not_supported, because KiCad 10's Schematic Editor has no API.
- Checked on the pic_programmer demo board:
- Four zoom-ins took the editor from zoom 2.84 to 20.00, centred.
- 17 3D commands ran in 6.8 s, with isometric skipped.
- The orbit preset's 36 commands ran in 5.4 s.
- **kicad_lint_library: the standard's library lint** (engine 0.21.1, standard #28). The bridge's structural check and KiCad's own verdict now come with the shared content rules, each finding carrying its rule and severity.
- Footprints: no pads, zero-size pads, unnumbered and duplicate pad numbers, no courtyard, origin off the part, no silkscreen, no 3D body, no description.
- Symbols: no pins, unnumbered and duplicate pins, no footprint, footprint not found, pins without pads and pads without pins, no part number.
- kicad-cli's refusals pass through as tool_refuses_file.
- Linting a symbol library alone now finds its linked footprints ("Lib:Name": a Lib.pretty beside it, else KiCad's footprint library tables), so pins are checked against pads. Those footprints' own findings stay out, since they aren't the library being linted.
- KiCad's paste-only apertures (pads with no copper) and unplated holes need no number and no pin.
- A kicad-cli that doesn't answer in time is now reported as "verdict unknown", no longer as KiCad refusing the file.
- Checked: KiCad's Package_SO library (401 footprints) has no errors, and its split exposed pads are quiet: engine 0.21.1 counts touching pads with the same number as one land.
- Checked: a 6-pin symbol linked to a SOT-23-5 gives "pin 6 has no pad on Test:SOT-23-5".
- **kicad_update_footprints_from_library: the standard's reply** (#27, now a core verb).
- Each row carries footprint and library; the count is also given as differs.
- padsChanged lists what changed (type, shape, position, rotation, size, drill, layers).
- **Engine:** adom-eda-checks 0.21.1 (EDA Bridge Standard 0.24.2).
## 1.0.88 (2026-10-30 16:11 UTC)
NATIVE (Rust) build. 1.0.88: KiCad 10's design variants (the standard's variants).
- **kicad_variants (new):** which parts are fitted on which build, on the project's own files.
- Lists every variant with its not-fitted parts, its changed fields (alternates) and its description.
- Makes or changes a variant: marks parts not fitted, or puts them back. Describes or removes one.
- It writes what KiCad 10 writes: the variant list in the .kicad_pro, and each part's variation inside its instance on whichever sheet holds it. A .bak is kept beside every file written.
- KiCad reads the result back: kicad-cli's netlist for the variant must mark exactly those parts DNP, or the call fails with verify_failed.
- Unlike Fusion's read-only list, KiCad's verb edits variants. Field changes (another Value in a variant) are listed but made in KiCad's own variant editor.
- Checked on a copy of KiCad's pic_programmer demo (two sheets):
- Lite with P1, C1 and R1 not fitted: KiCad marks the same three DNP.
- R1 put back: C1 and P1 are left.
- A second variant with D1: matches.
- Lite removed: only Pro is left in the project.
- kicad-cli's BOM for Lite leaves out C1 and P1.
- **kicad_sch_zoom (new; the standard's sch_zoom):** finds parts on a schematic sheet and frames them. It's the schematic half of cross-probing; kicad_zoom_to is the board half.
- Answers where each part sits (mm) and which ones the sheet doesn't place.
- The proof frame is KiCad's own plot of the sheet, cropped to the parts with a margin and each part outlined.
- KiCad 10's Schematic Editor has no API, so the frame is a plot of the saved sheet and the open editor's view isn't moved.
- Checked: C1 on the pic_programmer root sheet, and U1, P2, C6 and C7 together on its pic_sockets sub-sheet, each outlined in the plot.
## 1.0.87 (2026-10-29 22:00 UTC)
NATIVE (Rust) build. 1.0.87: refusals the caller can fix no longer say they may be a bridge bug.
- **Every verb:** the "THIS MAY BE A KICAD BRIDGE BUG ... file an issue" line no longer appears on a refusal the caller fixes.
- That covers a missing or bad argument, a name or file that isn't there, unsaved changes, a stale revision, a DRC refusal, no simulation model, a missing reason, and not supported.
- Unexpected failures still carry it.
- Before, kicad_current_capacity without its nets told the AI to file a bug for its own missing argument.
- **kicad_simulate: noise analysis** (standard #23). `analysis {type: "noise", source, output, reference?, sweep, points, start, stop}` runs ngspice's .noise.
- It answers the onoise and inoise spectra (V/rtHz) as signals, and totals {onoise, inoise} in V.
- Checked: an RC filter's output noise is 4.0714 nV/rtHz, the resistor's sqrt(4kTR). The total is 0.2035 uV against sqrt(kT/C) = 0.2036 uV.
- **kicad_simulate: Monte Carlo** (standard #23). `monteCarlo {runs, distribution: uniform|gaussian, seed, tolerances: {resistor, capacitor, inductor, dcSource} %}`.
- Every part of a kind with a tolerance is drawn again for each run. Uniform draws stay within the tolerance; gaussian draws use sigma = tolerance/3, clipped to the tolerance.
- Each run's step lists the values drawn, and the same seed draws the same values.
- Transistor and digital tolerances are refused with not_supported.
- Checked: on an inverting amplifier, every run's gain matches 20*log10(R2/R1) from its own drawn values, less the op-amp model's finite-gain error.
- **kicad_height_check and kicad_placement_check: turned parts** (engine 0.20.0, standard #26). A part turned off the 90° grid now sends its body's real rectangle, so it no longer collides through its bigger bounding box.
- Checked: StickHub, with a 45° LQFP and its decoupling caps, went from 70 false collisions to 1.
- That 1 is a crystal tucked into the LQFP's lead-free corner, which a body box (leads included) can't tell apart. KiCad's courtyard DRC passes.
- **Engine:** adom-eda-checks 0.20.0 (EDA Bridge Standard 0.23.0).
## 1.0.86 (2026-10-29 21:25 UTC)
NATIVE (Rust) build. 1.0.86: fixes found by testing 1.0.85 on real boards.
- **kicad_review_board:** KiCad's per-pin "unconnected-(U5-PB0-Pad16)" nets now count as no net, the way kicad_schematic_review treats them.
- KiCad gives every pin the schematic leaves unconnected a net of its own, so each one used to come back as a one-pad net warning.
- Checked: the ESC board went from 23 such warnings to a clean review. The rp2040 sample's real findings are unchanged.
- **kicad_review_board: the vendor part number and datasheet checks now read the symbols' fields.** The parts sent from KiCad's netlist used to carry none, so every part was flagged even when it had Mouser, DigiKey and LCSC numbers.
- Empty fields, and KiCad's "~" for no datasheet, don't count.
- Checked: on a copy of the rp2040 sample, giving C1 its Mouser, DigiKey and LCSC numbers and a datasheet clears both of its findings.
- **kicad_footprint_from_land_pattern** (engine 0.19.1, standard #25, found testing 1.0.85):
- SOT-23-5's pins 4 and 5 now line up with pins 1 and 3 (±0.95 mm). Before, they sat 0.95 mm apart, centred, so the part did not fit.
- The courtyard holds the pads and body only, so a 7 mm BGA's is symmetric at ±3.75 mm instead of stretching to the pin-1 dot.
- **Engine:** adom-eda-checks 0.19.1 (EDA Bridge Standard 0.22.2).
- **Verb tests:** the test run never overlaps another bridge's test run on the same machine. It waits up to 30 minutes, then refuses (#112).
## 1.0.85 (2026-10-29 20:44 UTC)
NATIVE (Rust) build. 1.0.85: simulation sweeps and the parts a run left out, and footprints from a datasheet's land pattern laid out by the standard's engine.
- **kicad_footprint_from_land_pattern:** the standard's engine lays the footprint out, and KiCad's own writer turns it into the .kicad_mod and the 3D body box.
- The layout is the same as before: KiCad's code and the engine's both came from the Altium bridge, line for line. One copy now, so the engine's fixes reach KiCad.
- It covers pad numbering for chip, dual, SOT, quad and BGA packages, the exposed pad, the courtyard, silkscreen clear of the copper with a pin-1 dot, and a fab outline with a pin-1 chamfer.
- Replies carry engine. A missing number is still named ("dual needs padLength (mm)").
- Checked: a 3x3 mm QFN-16 with exposed pad was built live and read back by KiCad with 17 pads and its 3D model.
- **Engine:** adom-eda-checks 0.19.0 (EDA Bridge Standard 0.22.1).
- A width rule with only a minimum (Fusion's EAGLE rules) now counts as the board's track width.
- The engine's new panelize and teardrops plans are not used here: KiCad keeps its own kicad_teardrops (KiCad's own teardrop generator) and kicad_panelize.
- **kicad_simulate and kicad_export_spice: notSimulated** (standard #23, as Altium 0.2.82 reports it). These are the sheet's parts that KiCad left out of the netlist because they have no simulation model.
- A partly modelled sheet still runs, and the reply says which parts the result does not cover. KiCad writes a part with no model as a stub with no nodes (J1 __J1), which made ngspice refuse the whole circuit; the run now leaves those stubs out.
- A sheet where no part has a model refuses with no_model instead of an ngspice error.
- Parts the designer excluded from simulation are left out on purpose and are not listed.
- Checked: an RC with a connector on its output runs and names J1; a sheet of two connectors refuses no_model.
- **kicad_simulate: sweeps** (standard #23, as accepted from Altium). Arguments: `sweep {parameter, start, stop, step, scale?}` and `temperatures {start, stop, step}`.
- ngspice has no .step, so the circuit runs once per value: a part's value ("R4") is set with alter, a model parameter ("Q1.BF") with altermod on the part's model, and the temperature with .temp.
- Each run's signals carry step ("R1 = 2k", "T = 85"); the reply says how many runs there were (at most 50).
- A part that isn't in the netlist, or a model the netlist doesn't define, is refused with bad_args, never one run passed off as the sweep.
- Checked live:
- R1 at 1k and 2k puts the RC filter's corner at 1588 Hz and 794 Hz.
- A diode's forward voltage is 753, 696 and 639 mV at -10, 25 and 60 °C.
- Its emission coefficient N at 1 and 2 gives 0.69 V and 1.38 V.
## 1.0.84 (2026-10-29 19:49 UTC)
NATIVE (Rust) build. 1.0.84: a whole-board design review, and the standard's engine 0.17.2.
- **kicad_review_board (new; the standard's review_board):** one read of the board, and of the schematic beside it through KiCad's own netlist, reviewed by the standard's engine.
- Finds duplicate designators, parts off the board or near its edge, placeholder values on the board and the sheets, one-pin nets, parts without a footprint, missing vendor part numbers and datasheets, and disabled or missing design rules.
- Board Setup's clearance, track width and minimum through hole go in as the board's rules. KiCad's DRC always checks shorts, clearance, track width and hole size, so no rule class reads as missing on a KiCad board.
- skipped and notImplemented name what it could not judge (a placement grid needs gridMm; decoupling is kicad_schematic_review's job).
- Checked: the rp2040 sample's 12 PIN** test points come back as a duplicate designator, its 20 parts without vendor part numbers as warnings.
- **kicad_schematic_review:** each part now carries its value and comment too.
- **Engine:** adom-eda-checks 0.17.2 (EDA Bridge Standard 0.20.2).
## 1.0.83 (2026-10-29 19:26 UTC)
NATIVE (Rust) build. 1.0.83: a schematic review before the board is updated, and the standard's engine 0.16.0.
- **kicad_schematic_review (new; the standard's schematic_review, which KiCad answered only in part before):** reviews every pin against KiCad's own netlist of the design, with each pin's electrical type.
- Errors: power pins on no net, outputs driving each other.
- Warnings: pins on no net, one-pin nets, inputs nothing drives, and IC supplies with no decoupling capacitor to ground.
- KiCad's single-pin unconnected-(...) nets count as no net, and a pin with a no-connect flag is expected to be unconnected.
- Checked: a wired RC filter is clean; the unwired rp2040 sample shows its 5 unconnected power pins and 2 supplies without a capacitor.
- **Engine:** adom-eda-checks 0.16.0 (EDA Bridge Standard 0.19.0). KiCad keeps its own route_pair, length_tune, auto_classes, silk_designators, pin_pad_check and find_space: they work on KiCad's real courtyards and its live editor.
## 1.0.82 (2026-10-29 18:43 UTC)
NATIVE (Rust) build. 1.0.82: five more of the standard's app-tier verbs, and KiCad's own Python from the bridge.
- **kicad_eval:** a Python snippet run with KiCad's bundled Python and its pcbnew module, headless.
- With filePath the board is loaded as `board`, and the snippet's `result` comes back as JSON.
- Checked: 149 footprints and 83 nets read in 0.4 s; a failing snippet returns its traceback.
- **kicad_run_script:** a .py of your own run the same way, with arguments; stdout, stderr and the exit code come back.
- **kicad_foreground:** brings a KiCad window to the person. It needs a reason written for them, captions it first, and refuses without one.
- **kicad_dialog_log:** every dialog the bridge's sweeps dismissed since it started, newest last.
- **kicad_license_status:** KiCad's licence in plain words: GPL-3.0-or-later, no seat, sign-in or trial.
## 1.0.81 (2026-10-29 17:52 UTC)
NATIVE (Rust) build. 1.0.81: the standard's engine 0.12.2 and two assembly-check fixes.
- **kicad_assembly_check** (standard #24):
- pads sharing one centre (one land drawn as several pads) no longer read as a 0 mm pitch;
- a footprint with no pads (a logo) no longer counts as a part, so a bottom-side logo no longer fails "parts on one side only".
- **kicad_plan_route** (engine 0.12.2): routes are smoothed into straight and 45-degree segments with the same clearance (smooth:false turns that off). A pour holding the route's own end pad is exempt from avoidPours (avoidExempt), and planner reports withoutAvoid.
- **Engine:** adom-eda-checks 0.12.2 (EDA Bridge Standard 0.15.2).
## 1.0.80 (2026-10-29 17:35 UTC)
NATIVE (Rust) build. 1.0.80: framing the view on a part or a net that works with KiCad in the background (wiki #121), and the standard's engine 0.11.0.
- **kicad_zoom_to (new; the standard's zoom_to):** frames the open PCB editor on parts ({refs}) or a whole net ({net}), or fits the board.
- It runs KiCad's own Zoom to Selected Objects through its API, so the view really moves while KiCad stays in the background. A menu command posted to a background window was acknowledged but did not move it.
- The selection it makes is cleared afterwards (keepSelection keeps it), and the API answers normally right after.
- Checked: U5 framed from zoom 4.5 to 33 in the background; a net and the whole board too.
- **kicad_select_net / kicad_select_items:** their hints now point to kicad_zoom_to.
- **Engine:** adom-eda-checks 0.11.0 (EDA Bridge Standard 0.14.0). KiCad keeps its own IPC-2581 exporter.
## 1.0.79 (2026-10-29 17:03 UTC)
NATIVE (Rust) build. 1.0.79: simulation in the EDA Bridge Standard's shape (standard 0.14.0, #23).
- **kicad_simulate** takes and answers the standard's simulate:
- analysis as {type: op | dc | ac | tran | raw, ...};
- probes by net ({net: "OUT"}) and source current ({current: "V1"});
- signals[{signal, x, y, xUnit, yUnit, phase}] with each probe's own points. points is a ceiling that always keeps the first, last and extreme points, and AC phase is unwrapped;
- engine names the ngspice and KiCad versions ("ngspice 46 (KiCad 10.0.7)").
- SPICE text, V(/OUT) probes and the earlier fields still work.
- **kicad_export_spice** says its dialect (ngspice).
- Both are now standard verbs (simulate, export_spice) rather than KiCad's own.
## 1.0.78 (2026-10-29 16:41 UTC)
NATIVE (Rust) build. 1.0.78: SPICE simulation from a KiCad schematic, headless, through the ngspice KiCad installs.
- **kicad_simulate (new, wiki #89):** runs a sheet through ngspice, the simulator KiCad itself uses.
- Analyses: transient, AC, DC sweep or operating point, given in the call or carried by the schematic.
- Probes are node voltages V(/NET) and source currents I(V1). Each comes back downsampled with its first, last, min and max (AC as dB and phase), and as a CSV file.
- ngspice runs in a child process, so a circuit that crashes it never takes the bridge down, and a failed analysis returns ngspice's own message.
- Checked: an RC low-pass of 1k and 100n is -2.99 dB and -44.9 degrees at 1.58 kHz, and passes 0.85 of a 1 kHz sine.
- **kicad_export_spice (new):** KiCad's own SPICE netlist of a sheet, with its elements, its analyses and the model files it includes.
- **Engine:** adom-eda-checks 0.10.4 (standard 0.13.4): plan_route keeps a pour holding the route's own end pad out of avoidPours, echoes its pour settings, and smooths grid staircases into straight and 45-degree segments.
## 1.0.77 (2026-10-28 21:57 UTC)
NATIVE (Rust) build. 1.0.77: fanout plans that are safe on a routed board, decoupling caps that leave room for the fanout, and the standard's engine 0.10.3.
- **kicad_plan_fanout:** now planned by the standard's engine, safe on a routed board (standard #22):
- pins whose net already reaches the pad are skipped (includeRouted plans them anyway);
- conflicts are measured against other nets' pads, tracks, arcs and vias;
- an exposed pad's via grid steps round holes already there;
- crossesPours names the pours the plan runs into.
- Each call comes back ready for kicad_route_net. The old argument names still work.
- **kicad_place_decoupling:** leaves room for the IC's fanout (leaveFanout, default true): no cap pad lands on the escape stubs or vias of the IC's other pins. Checked on the ESC board's U5.
- **Fix:** 1.0.76's fanout conflict check missed every stub starting at a pad and measured a stub against a pad as an outline. It is now correct, with regression tests.
- **kicad_plan_route** (engine 0.10.3): avoidPours takes a list of nets, and pourCost makes crossing pours a soft cost.
## 1.0.76 (2026-10-28 21:31 UTC)
NATIVE (Rust) build. 1.0.76: fanout conflicts, routes that know the pours, the tour template back, and the standard's engine 0.10.0.
- **kicad_plan_fanout:** conflicts[] lists every planned via and stub closer than the clearance to another net's pad anywhere on the board, measured by the pad's real outline. Vias count on every layer, stubs on their own layer (standard #22).
- **kicad_plan_route** (engine 0.10.0, standard #21):
- crossesPours names other nets' pours the route runs through, and avoidPours:true keeps it out of them;
- through vias are checked on every copper layer;
- the board's strictest clearance rule decides.
- **kicad_place_decoupling:** a cap the plan can't move keeps its spot, so no other cap is planned onto it.
- **Tour template (wiki #136):** tour-pack/template is rebuilt: one AdomTour R_AdomTour on a sheet, a small board and a project. The default kicad-tour pack has its files again.
- KiCad 10.0.7 opens all three; the only ERC/DRC findings are the unconnected resistor and the AdomTour library, which the tour installs.
- The 7 schematic unit tests that read it pass again.
## 1.0.75 (2026-10-28 21:05 UTC)
NATIVE (Rust) build. 1.0.75: decoupling caps sorted by the IC they belong to, routes planned at the board's net class, and the standard's engine 0.7.0.
- **kicad_place_decoupling:** by default it now leaves out two kinds of cap, listed in leftOut[] (standard #22):
- signal_net: a net not named like a supply with only one cap to ground, such as a crystal's load cap;
- nearer_another_ic: a cap nearer another IC's pin on the same net.
- On the ESC board, U1 no longer takes every +VBAT cap: they split between U1 and U2. Naming caps still places them as asked.
- A through-hole pad of a part on the other side now blocks the spot too.
- **kicad_plan_route:** the project's Default net class goes to the engine as the board's width and via rules, and planner.widthFrom / viaFrom say which rule set them.
- **kicad_open_board:** when KiCad's API serves another PCB editor's board, it now says so (api_serves_another_board), not "a different board with the same file name".
- **Engine:** adom-eda-checks 0.7.0 (EDA Bridge Standard 0.10.0).
## 1.0.74 (2026-10-28 20:40 UTC)
NATIVE (Rust) build. 1.0.74: 3D bodies made from package dimensions and routes planned between pads, both from the standard's engine 0.6.0.
- **kicad_generate_body (new):** a part's 3D body from its package family and the datasheet's JEDEC letters, to IPC-7351 proportions, with an optional marking on top.
- Families: chip, SOIC, QFN, QFP, BGA, SOT-23, DFN, MELF, can, crystal and header.
- The engine writes the STEP. With libraryPath it goes in <Lib>.3dshapes, and footprintName attaches it.
- Checked: a SOIC-8 marked LM358 sits on its footprint's pads at 1.75 mm.
- **kicad_plan_route (new):** a path for one net between two pads, around the board's copper and inside its clearance rules, on the layers allowed, with vias where they help. Nothing changes.
- routeNet is kicad_route_net's own arguments, ready to run.
- Checked on the ESC board: /DRV_GHC (R12.1 to U4.13) is a 2.5 mm F.Cu path, and kicad_route_net took it unchanged with no new DRC error.
- **Engine:** adom-eda-checks 0.6.0 (EDA Bridge Standard 0.9.0). These were KiCad's last two standard verbs outside the app tier.
## 1.0.73 (2026-10-28 20:13 UTC)
NATIVE (Rust) build. 1.0.73: parts framed in KiCad's own render, a stricter painted-canvas check, and the standard's engine 0.4.1.
- **kicad_render_board ref / refs (wiki #105):** frames those parts in KiCad's own renderer.
- The camera pivots on the parts' pad centre and zooms to fit them with marginMm around; data.framed reports the pivot and zoom.
- rotate "-45,0,45" gives an isometric view.
- Checked on the ESC board: J1 is centred, top, bottom and iso; J1 with Q1 frames both.
- **canvasRendered (wiki #100):** a canvas now also needs 10% of its sampled rows to vary.
- A blank white 3D viewer with one black strip (John's capture) had passed; it is now reported as not drawn.
- Real views measured 33 to 100%.
- **kicad_footprint_models:** the battery now changes a model's offset live, reads it back and restores it (wiki #101).
- **Engine:** adom-eda-checks 0.4.1 (standard 0.7.1). placement_check lists a part under a raised one as `stacked`, not as an overlap.
## 1.0.72 (2026-10-28 19:28 UTC)
NATIVE (Rust) build. 1.0.72: four more checks from the standard's engine 0.4.0 (EDA Bridge Standard 0.7.0), and a placement review.
- **Engine:** adom-eda-checks 0.4.0, vendored unchanged. Every engine reply now carries the engine's own `engine` field instead of a version written by hand.
- **kicad_thermal_vias and kicad_via_fence:** planned by the engine, as all three bridges now do (standard #18).
- The via comes from the project's Default net class, and the fence's clearance from the board's largest clearance rule.
- KiCad's DRC still runs before any via is placed, live or in the closed file.
- **kicad_height_check:** computed by the engine from kicad_bodies; `complete` says whether every part had a body (standard #19).
- **kicad_placement_check (new):** a placement review before routing, from the engine with the parts' 3D bodies.
- It finds parts whose pads and bodies overlap on one side, parts off the board or over its edge, pads near the edge, and parts on a mounting hole.
## 1.0.71 (2026-10-28 19:00 UTC)
NATIVE (Rust) build. 1.0.71: pictures of library parts, and layer visibility in the open board.
- **kicad_library_views:** each part in a library drawn for review, as image files, headless (kicad-cli; nothing opens).
- The symbol, one PNG per unit; the footprint with its pad numbers; the 3D body seated on its pads, an isometric view zoomed out for a tall body.
- The device view: an SVG table of every symbol pin against a footprint pad, with any pin without a pad and any pad without a pin listed.
- From a .kicad_sym the footprint is the symbol's Footprint field; from a .pretty folder, symbolLibraryPath gives the symbol.
- A footprint with no model, or a model file that does not resolve, is reported ok:false for 3d, never drawn empty.
- **kicad_set_layer_visibility:** shows or hides one layer of the open board (by name or layer id) and reads it back.
## 1.0.70 (2026-10-28 17:55 UTC)
NATIVE (Rust) build. 1.0.70: schematics drawn from a netlist, a plan-only library-bundle install, and the standard's engine 0.2.1.
- **kicad_build_schematic:** a new sheet (and project) from a parts list and a netlist with library symbols.
- One column per block, a stub and a net label on every connected pin, and the title block filled.
- Then KiCad's own netlist of the sheet is compared with the nets given, pin by pin, and ERC runs.
- **kicad_install_library_bundle planOnly:true (wiki #106):** installs nothing.
- It answers the steps with time estimates, and per part the evidence the install will give: symbol always, footprint when the bundle has it, 3d when its model is in it.
- The real install now reports steps[] with the same ids.
- **Engine:** adom-eda-checks 0.2.1 (EDA Bridge Standard 0.5.1), vendored unchanged; nothing in KiCad's checks changes.
- The checks' engine field had kept saying 0.1.2 since 1.0.67; a test now ties it to VENDOR.md.
## 1.0.69 (2026-10-28 17:28 UTC)
NATIVE (Rust) build. 1.0.69: length tuning, mouse-bite panels, silkscreen prep, component classes, new boards from footprints, and schematic sheets read from the file.
- **kicad_panelize separation:"tabs":** the copies stand gapMm apart (2 mm default) inside a frame with rails all round.
- Each board's edges are broken at its tabs on Edge.Cuts (the rout path), and every tab carries five 0.6 mm mouse-bite holes on the board side.
- The tab layout and JLCPCB's panel rules (for tabs and for V-score) are the Altium bridge's, and the reply now carries them as jlcpcb.rules, with boardsAt and nearestCopperToEdge.
- **kicad_build_board:** a new board from a parts list and a netlist: the outline (a rectangle with rounded corners, or a polygon), every footprint from its library by its own origin, pad nets set, read back pin by pin.
- **kicad_test_board:** one footprint or a ';' list from a library on a new board, or added to an existing one.
- **kicad_read_sheet_file:** a .kicad_sch's parts read from the file (designator, symbol, value, uuid, unit, position, fields and pins), one entry per placed unit.
- **kicad_length_tune:** lengthens a net to targetMm, or to matchTo's length (pair skew, a byte lane). It draws a serpentine of square bumps in its longest straight track with room on one side, sized to add exactly the missing length, clear of other copper and the edge. Live as one Undo step, or in the closed file, after KiCad's DRC shows no new error.
- **kicad_silkscreen_prep:** on a closed board, in one call:
- turns on KiCad's own clipping: the Gerbers subtract the solder mask from the silkscreen;
- deletes silkscreen lying outside the board;
- moves designators that sit on pads;
- reports KiCad's silk DRC counts before and after.
- **kicad_component_classes:** lists, makes or removes KiCad 9+ component classes. An optional room is a rule area plus a custom DRC rule that flags any member outside it. Both were checked against KiCad 10.0.7's DRC.
## 1.0.68 (2026-10-28 16:15 UTC)
NATIVE (Rust) build. 1.0.68: ordering and footprints, five more of the EDA Bridge Standard's verbs.
- **kicad_bom:** the schematic's parts merged with the board, one line per MPN, checked for what an order lacks.
- Writes bom.csv, JLCPCB's BOM and CPL, the Mouser and DigiKey BOM-tool files and bom.json.
- The grouping and the field names matched across libraries are the Altium bridge's, so the files read the same in both tools.
- **kicad_assembly_check:** the board against JLCPCB's Economic and Standard assembly tiers, and the cheapest one it passes. Parts the line never places (excluded from BOM or position files, DNP, board-only) are left out.
- **kicad_jlcpcb_order:** in one folder:
- the fab check;
- the Gerbers and drill, zipped;
- the BOM and CPL;
- the assembly tiers;
- the order-form values;
- every issue in one list, with `ready`.
- **kicad_footprint_from_land_pattern:** a footprint from a datasheet's land pattern (chip, SOIC/DFN, SOT, QFP/QFN, BGA, exposed pad), with silkscreen clear of copper, pin-1 marks, the courtyard and a 3D body box.
- **kicad_silk_designators:** every reference designator placed upright beside its part, clear of pads, bodies, existing silkscreen and the other labels, never below the board's minimum text height.
- A closed board gets the labels written into the file. KiCad's DRC checks the result first, and a label it flags is reported, not written.
- A board open in KiCad is moved live as one Undo step, unless its footprints carry KiCad 10's units block: then it refuses, nothing changed (see below).
- **Fixes:**
- kicad_silk_fields_batch no longer drops footprints' units blocks. KiCad 10.0.x moves a field only by sending its whole footprint back, and loses the footprint's units block (pin groups) doing so. Such a move now refuses with field_move_drops_units, nothing changed, unless allowUnitsDrop:true.
- kicad_silk_state gives a part with a round courtyard its real body box, not a flat line.
- The netlist reader keeps symbol fields and DNP flags for the BOM.
## 1.0.67 (2026-10-27 22:24 UTC)
NATIVE (Rust) build. 1.0.67: board checks, the EDA Bridge Standard's checks tier: 14 verbs that check a board and place the vias a check asks for.
- **The standard's shared engine** (adom-eda-checks, vendored unchanged): kicad_return_path (with a ready kicad_apply_zone_plan that closes each gap), kicad_copper_balance, kicad_impedance (with ready kicad_custom_rules width and pair rules), kicad_current_capacity, and kicad_fab_check: the board against a fab's record from adom/pcb-design-rules (fab:"jlcpcb"), naming the page and the date it was read. kicad_validate_for_fab stays as KiCad's own DRC check. kicad_silk_state also answers the standard's shape (components, lines, texts with x, y and size).
- **Computed by the bridge:** kicad_net_lengths (pair skew, matched-length groups), kicad_check_orientation, kicad_find_space, kicad_height_check (3D heights, regions, collisions), kicad_pin_pad_check (symbol pins against footprint pads), kicad_auto_classes (net classes from names, written with apply).
- **Vias:** kicad_thermal_vias fills an exposed pad and kicad_via_fence lines fast tracks and/or the board edge with ground vias. Both run live as one Undo step, or into the closed file, and only after KiCad's DRC (pours refilled) shows they add no error.
- **kicad_board_report:** every check, plus DRC, ERC, the board against the schematic and the fab's limits, with a rendered picture, in one HTML file.
- **Fix:** kicad_update_pcb_from_schematic no longer reports nets with a slash in their name as changed: the board writes /VPP{slash}MCLR and the netlist /VPP/MCLR. On KiCad's pic_programmer demo it reported 11 false changes, and apply would have renamed those nets.
## 1.0.66 (2026-10-27 21:14 UTC)
NATIVE (Rust) build. 1.0.66: teardrops and V-score panels, two more of the EDA Bridge Standard's native verbs.
- **teardrops:** adds or removes teardrops with KiCad's own Edit > Edit Teardrops dialog (KiCad's API has no teardrop call), on PTH pads, SMD pads and vias, optionally track to track or the selection only. It counts the teardrops before and after and returns the board's new revision. The board's default teardrop shapes are used.
- **panelize:** steps a rectangular board into a V-score panel as a new board file:
- rows x cols copies, each with its nets renamed B<n>-<net>;
- one outline with rails, V-cut lines on Cmts.User, and three tooling holes and three fiducials;
- KiCad's DRC on the panel, compared with the board's own: newErrors counts only what the panel adds.
A shaped board is refused, because it needs mouse bites.
## 1.0.65 (2026-10-27 20:14 UTC)
NATIVE (Rust) build. 1.0.65: any library footprint can now be added to a board open in KiCad, plus four of the EDA Bridge Standard's native verbs.
**Live adds without a copy on the board.** add_footprint and add_mounting_hole build the part from its library text as KiCad's protobuf items (commit:"create-items", one Undo step): pads, graphics, texts, fields and 3D models.
- When the same library footprint is already on that side of the board, KiCad's own encoding of it is still copied.
- Checked on KiCad 10.0.7: stock parts with through-hole and SMD pads, at 0, 45, 90 and 270 degrees and on the back, came out the same as the closed-file add. DRC reports no library mismatch for them.
- A footprint with custom-shape pads, mask or paste margins, or zones inside still refuses with live_create_unsupported and says why.
**New standard verbs:**
- **compile:** ERC and the netlist, with messages counted by class;
- **list_installed_libraries:** every symbol and footprint library KiCad loads, with missing ones flagged;
- **replicate_layout:** one channel's placement onto matching channels through move_footprint, one Undo step;
- **diff_pairs:** the pairs KiCad's router recognises by name, and the net class that sets their width and gap.
## 1.0.64 (2026-10-27 19:27 UTC)
NATIVE (Rust) build. 1.0.64: adds to a board open in KiCad, two fixes for footprints KiCad rebuilds over its API, and 17 of the EDA Bridge Standard's core verbs.
**Adding items to an open board.** KiCad 10.0.x creates nothing from text over its API, so the bridge now encodes the new items as KiCad's protobuf items itself (commit:"create-items", one Undo step):
- board_outline and import_svg are created live;
- add_footprint (with duplicateOf and count) and add_mounting_hole create a part live when the same library footprint is already on that side of the board with the same pads and graphics: the bridge copies KiCad's own encoding of it, with fresh ids, the new pose, reference, value and pad nets;
- anything else, a footprint the board lacks and update_footprints_from_library included, still refuses with live_create_unsupported, now with liveCreateWhy.
**Footprints KiCad rebuilds over its API (#126, #129).** KiCad stores every footprint it rebuilds without a polygon's repeated closing point, which DRC then reports as lib_footprint_mismatch:
- moves, live field edits and live part edits now name those parts in closingVerticesDroppedByKiCad, with how to restore them;
- a live field move (silk_fields_batch) no longer fails otherBoardDataVerified because of it.
**New standard verbs:**
- **footprint libraries:** copy_footprint, rename_footprint, remove_footprint, xcopy_footprint, add_body;
- **symbol libraries:** clone_symbol, rename_symbol, set_params, set_visibility, symbol_prims;
- **sheets:** place_on_sch, doc_params, sheet_params (the BOM write-back onto placed parts), part_parameters;
- **the board:** layers, silk_state, ripup_nets.
## 1.0.63 (2026-10-27 18:18 UTC)
NATIVE (Rust) build. 1.0.63: the EDA Bridge Standard's shapes for the 47 verbs KiCad brought to the standard (standard 0.3.0). KiCad's own names and arguments keep working.
- **Standard names:** render_board_3d, remove_parts, edit_parts, align_parts, remove_graphics, read_footprint, export_library_part, create_part_project. kicad_edit_footprint with library arguments edits the library footprint (fp_edit), as the standard means it.
- **Standard arguments:**
- sheet and project paths;
- id/ids for KiCad's uuids;
- mm-named numbers;
- bomFields on IPC-2581;
- at and box on import_svg and copy_routing.
- **Lists are one write:** sch_connect_pins pairs, sch_bus_entry entries, sch_edit_label edits, sch_text texts and sch_junction add+remove run as one kicad_sch_batch. kicad_edit_parts takes `edits: [{ref, ...}]`, a different edit per part, in one undo step, live or on the file.
- **y up:** frame:"standard" on all 47. Sheet verbs answer y up too; sch_pins also answers one flat pins list.
- **estimate_cost** names its price source (the bridge's built-in JLCPCB-style rates; no check date is recorded) and lists prices per quantity.
- **create_part_project** refuses to overwrite an existing project unless overwrite:true.
- **kicad_describe** marks these verbs with standardShape.
- **The release script** now pushes only reference/kicad-<ver>.json to the standard, which standard-lane owns.
- **Battery:** phase 9 runs the standard shapes on a real KiCad.
## 1.0.62 (2026-10-27 16:30 UTC)
NATIVE (Rust) build. 1.0.62: John's 1.0.61 verbs (Konnect parity) brought into the EDA Bridge Standard and the verb battery. Sixteen standard names now answer as aliases of the verbs that do the same job (net_classes, repour, save, update_pcb, annotate, create_symbol, create_footprint, read_symbol, remove_symbol, sch_sheet_symbol, selection, route_pair, fab_check, find_symbol, export_manufacturing, add_rule); a catalog test makes every new verb a standard name, an alias or a reviewed KiCad-only job, and each release now syncs bridge.json, refreshes the standard's KiCad coverage and writes every verb into the README. Fixes: adding items to a board open in KiCad (add_footprint, add_mounting_hole, import_svg, board_outline, update_footprints_from_library) failed as a vague rollback; KiCad 10.0.x (4 and 7 checked) creates nothing from text over its API, so these now refuse with live_create_unsupported and say to close the board, which edits the file; a KiCad lock file left by a KiCad that is no longer running no longer blocks file edits. The verb battery covers all 227 verbs on KiCad 10.0.7, the 78 new ones in project, schematic, library, fab and board scenarios.
## 1.0.61 (2026-10-27 14:58 UTC)
NATIVE (Rust) build. Every Konnect v0.13.0 capability, 211 verbs (was 133; docs/konnect-gap.md maps all 228 Konnect tools). Schematic: components, pins, items, rotate, region move, annotate, replace and update symbols, field reset, wire delete/split, labels, junctions, net stubs, pin-to-pin wiring, text, buses, atomic batches, sheets and hierarchy, sheet pins, connectivity trace, checks, connectivity fixes, PNG render with visual baselines, design review. Board: outline, layer count, graphics, mounting holes, SVG import, refill, save, add/flip/delete/edit/align footprints, update footprints from library, footprint graphics and 3D models, selection and cross-probe, update PCB from schematic. Routing and rules: modify track, diff pairs, copy routing, netclasses, board rules, custom rules, clearance check, placement score, decoupling placement, fanout plan. Fab: DXF, GenCAD, IPC-2581, ODB++, IPC-D-356, one-zip fab package, fab pre-flight, cost numbers. Projects and libraries: create, info, rename, snapshot; footprint and symbol create, edit, info; library search. PCM: file:// and private wiki repositories, zipPath installs (#132).
## 1.0.59 (2026-10-26 22:55 UTC)
NATIVE (Rust) build. 1.0.59: the EDA Bridge Standard board model. kicad_routing_state {model:"standard"} answers the standard's board model (mm, y up, custom pads as rectangles with copperPoints, the outline with arcs, unconnected from the copper with isolatedCopper, an order-independent revision), live or from the file; the edit verbs take its revision and, with frame:"standard", its coordinates. New: kicad_layer_stack, kicad_pour_state, kicad_bodies (3D heights from STEP/VRML), kicad_netlist (expect comparison, pin types), kicad_board_summary, kicad_list_nets, kicad_list_designators, kicad_copper_layers, kicad_layers_in_use, kicad_component_data, kicad_component_pins, kicad_sch_no_connect (#131). Fixes: kicad_remove_route honours dryRun (#134); placement outline box follows arcs and circles, ring courtyards no longer collide (#133); PCM libraries resolve ${KICAD10_3RD_PARTY} (#130); the no-ipc build compiles again. Unconnected matches KiCad's DRC on six KiCad 10 demo boards; verb battery on DESKTOP-BAR6S0F (KiCad 10.0.4).
## 1.0.1 (2026-09-12 13:54 UTC)
NATIVE (Rust) build. 1.0.1: Freerouting on the user's terms. kicad_freerouting {status|install|uninstall} installs Freerouting's own self-contained bundle (88 MB download, 147 MB on disk, its Java runtime inside, nothing installed on the PC, no UAC) only when the user asks, as a background job with progress in status, and removes it on its own. kicad_autoroute {engine: freerouting} writes the Specctra DSN from the board, routes headless with a deadline, and lands the SES copper as native undo steps through the IPC API (or into the closed file with a backup), then DRC. Every autoroute reply names both engines; the AI engine stays the recommendation. Verified on ConfRoomROG: install 6 s, six-net fixture in 3 s, DRC clean, live apply six undo steps, uninstall clean. kicad_uninstall removes the engine too. New kicad-autorouting skill.
## 1.0.0 (2026-09-12 12:36 UTC)
NATIVE (Rust) build. Native bridge 1.0.0: one Windows executable, no Python or PowerShell, nothing for ab to provision. 96 verbs: everything the Python bridge did plus schematic edit in place (six verbs, ERC-validated), kicad_autoroute (ai engine live), kicad_rescan_libraries verified by loading, kicad_progress and verb_times, a multithreaded server so status and progress polls answer during long verbs, the etiquette loop inside the binary, and the six-beat tour. Live routing on the Rust IPC client with the same revision guard and native undo steps. Gate on ConfRoomROG from this exact zip: 71 pass, 4 fail (three foreground notes from another session's Chrome windows, one cleanup-while-open), 15 skip; kicad_demo passing. In-KiCad Python plugin retired. Known: ab's native recorder drops 4K takes past a minute (adom-bridge#189).
## 0.9.351 (2026-09-11 11:36 UTC)
Rust port plan phase 0: seeds KiCad's six do_not_show_again nags, api.enable_server, update-check and eeschema prompt suppression at first-run config seeding (bridge-created files only, never a user's own settings); deletes dead launch_editor.ps1, unused handlers/foreground_guard.py and the legacy tour/ orchestrator. Plan and comparison sub-readmes published under docs/. Gate: ConfRoomROG 71 pass / 1 fail (known idle-box foreground grant on kicad_launch) / 15 skip; adom_library_heal verified live.
## 0.9.350 (2026-09-09 13:49 UTC)
kicad_model_check and model diagnostics on the 3D show verbs (#88)
## 0.9.350 (2026-09-09): 3D model diagnostics (#88)
- New read-only `kicad_model_check {library, footprintName}` or `{boardPath}`: per (model ...) reference it
reports where KiCad would look (project dir, then the 3D search paths; never next to the .kicad_mod),
whether the file exists, whether it is a STEP/VRML with geometry, hidden flags and implausible scale,
with coded warnings and hints. Footprints that need no body (test points, fiducials, mounting holes,
board-only parts) are exempt. `renderVerified` is always false: the viewer frame stays the render proof.
- `kicad_show_3d_chip` and `kicad_show_3d_board {filePath}` attach a `models` summary and a `_modelHint`
when a body cannot be there, so a pads-only 3D view arrives with its reason.
## 0.9.349 (2026-09-09 13:17 UTC)
kicad_status carries operation state for timeout recovery (#87)
## 0.9.349 (2026-09-09): kicad_status answers "did my operation finish?" (#87)
- `kicad_status` is the manifest's statusVerb, the verb ab tells a caller to poll after its 130 s
budget runs out. It carried plugin inventory only. It now also carries `operations`: every phase
in flight (all callers, each frame named), the last finished runs with ok/error and finishedAt,
and `yours` filtered to the caller. The run log records the caller and the error text of a failed
run so that answer is exact. Plugin liveness is unchanged.
## 0.9.348 (2026-09-08 20:32 UTC)
Focus guardian identity survives hwnd reuse; editors spawn without activation (pre-promotion run findings)
## 0.9.348 (2026-09-08): editors launched by open_board/open_schematic start without activation
- The focus guardian's "push a KiCad window behind the user once" now keys on (hwnd, pid) and expires
closed windows: Windows recycles hwnd numbers, so a new editor could inherit an already-pushed number
and never be pushed at all. The push stays one per window (John's rule). Editors opened by
open_board/open_schematic are spawned with SW_SHOWNOACTIVATE like kicad.exe. Measured on an idle
ConfRoomROG (no user input for minutes): a new editor still ends on top, because Windows grants a
new process the foreground once the foreground lock timeout has expired; with a user active Windows
blocks it. Not new behaviour; recorded here so the pre-promotion runner reading is understood.
## 0.9.347 (2026-09-07 19:10 UTC)
kicad_close honours unsaved work (#84); verified footprint rescan (#51)
## 0.9.347 (2026-09-07): kicad_close honours unsaved work (#84), footprint rescan verified (#51)
- `kicad_close` no longer force-kills an editor that is asking "Save changes?": it reports
errorCode unsaved_changes with the dialog text and leaves the window open. `discardChanges:true`
presses Discard for the caller and keeps the close graceful; `force:true` is still the only kill.
The graceful wait per window is 8 s (was 5 s).
- `kicad_rescan_libraries` takes footprints:["Lib:Name", ...] and loads each in the Footprint Editor after
the tree refresh, so `verified` is measured (the last one stays shown). Measured on 0.9.343: a footprint installed two hours after
pcbnew started loads after the in-place refresh, no restart. The stale-editor wording on
`kicad_install_footprint` now says that instead of demanding a process restart.
## 0.9.343 (2026-09-07 18:29 UTC)
Footprint loads with two pcbnew processes; list_footprints reads the fp-lib-table (#81)
## 0.9.343 (2026-09-07): footprint loads with two pcbnew processes (#81)
- The Library Tree toggle behind every background footprint load asked "the" pcbnew plugin and, with
two pcbnew processes alive, got a stray PCB Editor that has no Footprint Editor frame; the tree
stayed hidden and the load typed into nothing. It now asks the pcbnew that owns the Footprint Editor.
- `kicad_list_footprints` lists every library in the fp-lib-table with URIs expanded like KiCad does
(stock Resistor_SMD and friends included), not only Documents/KiCad/<ver>/footprints.
## 0.9.342 (2026-09-07 18:13 UTC)
First-run wizard deadlock: time-boxed dialog clicks and bounded sweeps (#83)
## 0.9.342 (2026-09-07): first-run wizard deadlock (#83)
- The dialog sweep clicked dialog buttons with a synchronous SendMessage. The first-run "KiCad Setup"
wizard opens its "Are you sure?" Confirmation modally inside the Cancel handler, so the click never
returned and the only code that would answer the Confirmation was the code waiting on the click.
On a truly fresh KiCad (config deleted) that held kicad_open_schematic past ab's 130 s budget.
Clicks are now time-boxed (SendMessageTimeout, 1.5 s) and both sweep loops stop after 25 s.
## 0.9.341 (2026-09-07 18:06 UTC)
Release-day fixes: stock library path resolution (#80), screenshot_all sizeKB (#81), readiness re-detect (#82), routing DRC completeness (PR 82), verified source pushes (#79), full verb-test coverage (#78)
## 0.9.341 (2026-09-07): release-day fixes from the multi-host verification
- #80: `${KICAD10_SYMBOL_DIR}` and the other stock library variables now resolve to the installed
KiCad's share directory (per-user installs included) with Configure Paths overrides honoured;
`kicad_list_symbols {"libraryName":"Device"}` works on every box.
- #81: `kicad_screenshot_all` no longer dies with an internal sizeKB error when a capture reply
carries no size.
- #82: `kicad_readiness` and `kicad_list_versions` re-detect when a cached kicad.exe has vanished
(KiCad uninstalled while the bridge ran) instead of reporting ready until a bridge restart.
- Live routing (PR 82, Codex): DRC snapshots refill zones; capped violation lists are flagged and the
error-delta check refuses to certify a truncated report (`drc_incomplete`, no copper changed).
- #79: the release tool verifies every source push and refuses to release on a failed chunk.
- #78: the verb test runner ships its rp2040 fixture, learns the Windows user from the box, covers every
live verb (tests or a stated skip), pings pcbnew instead of eeschema (no scripting there on KiCad 9/10),
and only counts a foreground steal when a user window was actually displaced.
## 0.9.340 (2026-09-07 16:56 UTC)
Live routing verbs through KiCad's IPC API (routing_state, route_net, remove_route, routing_validate), offline copper verbs (board_pads, add_track, add_via, route), kicad_ipc_api, KiCad 10 name-based nets, vendored routing deps
## 0.9.340 (2026-09-07): live routing through KiCad's IPC API
- New live copper verbs from the per-net routing branch: `kicad_routing_state`, `kicad_route_net`,
`kicad_remove_route`, `kicad_routing_validate`. Official KiCad IPC editing (KiCad 10.0.1+ with the
IPC API server on), native Undo per call, revision and net guards, snapshot DRC before commit.
- Offline file verbs for closed boards: `kicad_board_pads`, `kicad_add_track`, `kicad_add_via`, `kicad_route`.
- `kicad_ipc_api`: read or flip KiCad's IPC API server switch (needs a KiCad restart).
- The board parser reads KiCad 10 name-based nets as well as numbered nets.
- The release zip now vendors the IPC client (`routing_deps/`: kicad-python 0.8.0, protobuf, pynng,
cffi; Windows wheels for CPython 3.11 to 3.13). Nothing is pip-installed on the desktop.
- Not an autorouter and not an electrical sign-off: the caller chooses every waypoint.
- Tour work from 0.9.339 (two-part beats, 98% layout, 3D bodies) is unchanged.
## 0.9.339 (2026-09-05 19:16 UTC)
Tour motion: zoom depth per beat (one step for a single part, two plus one for a sheet or board)
## 0.9.338 (2026-09-05 18:55 UTC)
Tour: reopen the board when the file on disk is newer than the running pcbnew, so attached 3D bodies actually show
## 0.9.337 (2026-09-05 18:50 UTC)
Tour: a 3D model file that is not installed on this box counts as dead too; the MOSFETs then get KiCad's TDSON-8-1 body and the board reloads
## 0.9.336 (2026-09-05 18:46 UTC)
Tour: dead 3D model references are removed as balanced blocks (the regex missed the MOSFETs), so KiCad's TDSON-8-1 body attaches and the board reloads
## 0.9.335 (2026-09-05 18:43 UTC)
Tour: 3D body attach report lists what it saw for the MOSFET footprints (debug)
## 0.9.334 (2026-09-05 18:39 UTC)
Tour: two-part beats (A loads with its own line, B explains and moves once verified), part timestamps on the record, 3D body attach report says where it looked
## 0.9.333 (2026-09-05 18:36 UTC)
Tour: every beat in two parts (A loads the window with its own line, B starts once verified with the explaining line and the motion); part timestamps on the record; dead 3D bodies replaced by KiCad standard ones
## 0.9.332 (2026-09-05 18:29 UTC)
Footprint open: a hidden Library Tree filter box counts as missing (wx hides the pane, the control survives), so the pane is shown and waited for; tour prep summary (3D bodies attached, cache restart) on the progress record
## 0.9.331 (2026-09-05 18:22 UTC)
Footprint open: the plugin-free background loader also shows a hidden Library Tree pane before typing (arav-rog: the pane fix only covered the fallback path); tour reloads the board after attaching 3D bodies; prep summary on the record
## 0.9.330 (2026-09-05 18:11 UTC)
Tour: attach KiCad's standard 3D bodies to footprints the board left without one (six MOSFETs get TDSON-8-1); Footprint Editor Library Tree pane is shown once and waited for, never toggled back off
## 0.9.329 (2026-09-05 17:59 UTC)
Tour: restart KiCad during prepare when the footprint file is newer than the running KiCad (process start time vs file mtime), not only when it is new; startedAt and narrationAt on each step record
## 0.9.328 (2026-09-05 17:52 UTC)
Tour: footprint install leaves an identical file untouched (mtime bump made KiCad's cache look stale on every tour after the first); per-beat startedAt and narrationAt on the record for syncing a recording
## 0.9.327 (2026-09-05 17:32 UTC)
Tour: editor and viewer windows at 98 percent of the work area, centered (John)
## 0.9.326 (2026-09-05 17:21 UTC)
Tour: all editor and viewer windows at 95 percent of the work area, centered; 2D motion aims at the featured part (position parsed from the board and schematic) and checks the canvas after each gesture; 3D motion re-frames when the board is clipped or tiny
## 0.9.325 (2026-09-05 13:35 UTC)
Footprint open: when the Footprint Editor's Library Tree pane is hidden, show it through the frame's own View menu (plugin wm_command) before navigating; arav-rog had it hidden and every load failed
## 0.9.324 (2026-09-05 13:21 UTC)
Footprint open: never restart KiCad for a stale cache when the editor never opened (plugin_not_running restarted KiCad twice on arav-rog); tour footprint beat ensures pcbnew is open and its plugin alive; window rows carry minimized/image so 'in front' skips minimized windows
## 0.9.323 (2026-09-05 13:08 UTC)
Tour: a brand-new footprint restarts KiCad during prepare (before any window), never mid-beat; the footprint beat waits retryAfterMs on kicad_restarted_retry
## 0.9.322 (2026-09-05 13:07 UTC)
Tour: a brand-new footprint restarts KiCad during prepare (before any window), not mid-beat; install_footprint reports existedBefore; the footprint beat waits retryAfterMs on kicad_restarted_retry
## 0.9.321 (2026-09-05 13:03 UTC)
Tour: 'in front' ignores shell popups, minimized windows and our own overlays (arav-rog measured RustDesk minimized and PopupHost as the top window); footprint beat retries twice without the plugin wait; 2D motion recenters when a pan or zoom empties the canvas
## 0.9.320 (2026-09-05 12:50 UTC)
Tour: leave KiCad's main window as KiCad opens it; footprint beat waits for the project manager plugin and retries (cold KiCad on arav-rog failed both footprint beats)
## 0.9.319 (2026-09-05 12:47 UTC)
Tour: read the unwrapped desktop_list_windows payload (verify and foreground worked off a local list with no z-order on arav-rog); beat captions bottom-left clear of the demo panel; small top captions announce each foreground and the acks
## 0.9.318 (2026-09-04 23:13 UTC)
Wiki #48: the 20 s idle healer measured window reachability against the primary monitor only and pulled windows on a second monitor back to the primary; it now measures against the monitor the window overlaps
## 0.9.317 (2026-09-04 17:05 UTC)
Tour remote: dashboard presses recorded, acked with a caption, and honoured at the next gesture like panel presses
## 0.9.316 (2026-09-04 17:02 UTC)
Tour remote: FIFO press queue (no press lost), poll-drained presses recorded, presses on progress
## 0.9.315 (2026-09-04 16:53 UTC)
Tour remote: prev/next/pause cut the beat in flight at the next gesture; back goes to the beat before the one on screen; presses and acks recorded
## 0.9.314 (2026-09-04 16:25 UTC)
Tour layout: restore a window's bounds before the tour closes it so KiCad's sticky geometry is never corrupted
## 0.9.313 (2026-09-04 16:21 UTC)
Tour layout: read the unwrapped desktop_list_monitors payload so windows are placed in their 80 percent slots
## 0.9.312 (2026-09-04 16:20 UTC)
kicad_demo layoutProbe diagnostic; layout uses the monitor work area
## 0.9.311 (2026-09-04 16:14 UTC)
Fix: demo.py lacked the json import used by the new window-bounds save/restore (0.9.310 would have silently skipped saving bounds).
## 0.9.310 (2026-09-04 16:13 UTC)
Tour layout for the recording (John): each beat's window is placed at 80% of the primary screen in its slot (symbol upper-left, footprint nudged, chip 3D upper-right, schematic lower-left nudged, board 2D lower-left, board 3D lower-right) and the KiCad manager is centered at its own size; every bound is saved first and restored at the tour's end, stop, failure, or the next start (leftovers file), so KiCad's sticky sizes end up as the user had them. Every caption's reply is recorded on progress; a press on the remote gets an immediate acknowledgement caption at the top of the screen; the settle check waits up to 8 s for two identical captures instead of sampling once.
## 0.9.309 (2026-09-04 15:59 UTC)
Tour 3D beats no longer end with Zoom to Fit: in KiCad's 3D viewer that command also resets the orientation, so the board beat ended top-down on John's laptop; the beat now ends on the isometric it built (zoom in/out net to zero, framed at the opening fit).
## 0.9.308 (2026-09-04 15:59 UTC)
Motion gate: GetForegroundWindow can lag AD's z-order right after a raise, which aborted the symbol beat's motion at its first gesture on John's laptop while AD had already measured the window on top; the gate now waits up to 1.5 s for the OS to agree. Panel record keeps the callback URL across stage-advance shows.
## 0.9.307 (2026-09-04 15:52 UTC)
Tour verification (John: 'tool your bridge code to definitively know that the correct thing is showing'): every beat now MEASURES, after its raise, that its own window is the top of AD's z-order, that the live title carries the expected document, that the GL canvas is rendered (kicad_ui canvas probe) and that two captures 0.8 s apart are identical (settled). The result rides on the step and on progress as ; motion runs only on a verified window, otherwise the step says exactly which fact failed and which window was actually on top. Zoom discipline: 2D beats start and end on extents with two wheel clicks in and back out; 3D beats zoom one menu step in and out and end on Zoom to Fit while staying isometric.
## 0.9.306 (2026-09-04 15:46 UTC)
Tour 3D motion is now deterministic: KiCad's own View menu commands (Rotate X/Z by 10 degrees, Zoom In/Out, Zoom to Fit) resolved from the live menu bar and posted as WM_COMMAND, so the isometric and the orbit are the same on every DPI and need no mouse or foreground; mouse drags remain only as the fallback (they flipped the chip viewer and did nothing in the board viewer on 2026-09-03). Each step in the result now carries the window handle and title it drove.
## 0.9.305 (2026-09-04 15:38 UTC)
Tour window targeting (John's laptop: fourteen KiCad windows from days of demos; the 2D beat showed an empty untitled PCB Editor and the 3D beat the old sample cube): every beat now targets the tour's own document titles (esc-g431 schematic and board, the Adom STM32 symbol, the LQFP footprint), reuses an existing window instead of opening a duplicate, and opens each 3D view from that exact editor (open_3d_viewer accepts pcbHwnd/fpHwnd). The clean slate at start also closes old adom-demo documents and an empty untitled PCB Editor.
## 0.9.304 (2026-09-04 15:29 UTC)
Tour identity fix (John's dashboard run, 2026-09-03): ab refused the demo panel, every caption, every raise and every window close from the tour thread with 'carries no caller identity' (toast fallback, no captions, nothing in front). Every loopback call the bridge makes now carries identity: the X-Adom-Caller headers of the request being served, or the bridge's own self caller otherwise; the tour thread and ab's callback thread adopt the identity of the request that started the tour. Also: a failed panel show no longer demotes later tours to the toast (per-tour reset, one retry), and every 3D viewer plus the Footprint Editor are closed before the beats so the footprint beat opens a fresh, re-indexed editor.
## 0.9.303 (2026-09-04 15:15 UTC)
Tour sync: the verb-side control channel (kicad_demo {control}) is cleared at tour start too, so a pause/next/exit queued against a previous tour never steers a new one; completes the stale-press drain of 0.9.302.
## 0.9.302 (2026-09-04 15:13 UTC)
Tour sync fixes (John's run on 0.9.301): stale panel presses from the previous show are drained before a tour starts (his earlier NEXT presses made the new tour jump to step 3 at once); the narration mute is reset from the call's muted flag at thread start and pushed to the panel on the first show; STOP from the remote sets stopping on progress immediately so the dashboard can close its own pill; progress carries stopping.
## 0.9.301 (2026-09-04 15:07 UTC)
Taskbar hygiene (John: frozen progress bars on every KiCad window, no Adom badge): the boot sweep that clears leftover bars ran once at +6 s while ab was still restarting and failed silently; it now retries across the first two minutes until a window answers, and a five-minute idle reaper clears progress and badge on every KiCad window whenever the bridge is driving nothing. Filed adom/adom-bridge#138 for a progress TTL on ab's side.
## 0.9.300 (2026-09-04 15:01 UTC)
Tour 3D motion recalibrated: the orbit drags totalled about a third of the viewer width and turned the board nearly edge-on (KiCad's trackball is roughly 0.1 degree per pixel). Now ~30 degrees of tilt and ~40 of yaw for the isometric, then three gentle orbits with zoom, slower and smoother for the recording.
## 0.9.299 (2026-09-04 14:54 UTC)
Tour board-in-3D fix: KiCad's 3D viewers are unowned top-level windows, so picking 'the viewer owned by the PCB Editor' never matched and the chip's viewer was never closed (0.9.298 test-box run: board3d failed with the viewer actually open). The beats now take the viewer that APPEARS after their open, the chip's viewer is remembered and closed by handle before the board's opens, with the topmost viewer as fallback.
## 0.9.298 (2026-09-04 14:51 UTC)
Fix: the 0.9.297 tour job died on a NameError (_EXIT undefined) before its first progress update, so Play the demo showed the dashboard's transport pill and nothing else (John, lost, 2026-09-03). _EXIT is defined and the job's reset sits inside its try so any early failure lands on progress as an error instead of a silent stall.
## 0.9.297 (2026-09-04 14:08 UTC)
Tour: motion on every beat for the recording (fit, wheel zoom in/out, middle-drag pans in the 2D editors; Home, an isometric left-drag and three orbits with zoom in the 3D viewers), sent only while the beat's window is confirmed in front and aborted at the next gesture on STOP or when the user switches away. The board-in-3D beat now closes the chip's 3D viewer first and picks the viewer owned by the PCB Editor (the last beat was showing the chip's viewer by title match). STOP from the remote's X now clears the caption and ends the tour within the beat, audio already off. Per-beat motion reports ride on the result.
## 0.9.296 (2026-09-04 14:02 UTC)
Tour foreground fix (John: 'why do I not see you foregrounding any kicad window'): the beat raise called SetForegroundWindow from the bridge process and reported true regardless; Windows refuses that from a background process while the user works elsewhere. The bridge now lifts its no-activate mark, asks ab's desktop_bring_to_front to raise the beat's window once, and reports foregrounded only when the z-order afterwards shows that window on top.
## 0.9.295 (2026-09-04 13:55 UTC)
The tour now walks a real Adom board, adom/esc-g431 (149 footprints, 227 symbols): its STM32G431 symbol and LQFP-48 footprint are lifted from the wiki files at tour time and installed into the Adom library, then symbol, footprint, chip in 3D, schematic, board 2D, board 3D in that order. Captions were never painting because ab requires reason on desktop_caption; fixed, medium size, one line per beat. Narration re-rendered to match. Wording no longer claims the background: each beat's window is brought to the user once. Dead local 3D model paths in the board are dropped.
## 0.9.294 (2026-09-04 10:37 UTC)
Demo panel callback URL fix: the bridge read its bound port from a second copy of the server module and sent no eventCallbackUrl to ab (panel presses reached the tour only via poll). The port now travels through the environment, so every press is POSTed to the bridge the instant it is clicked. Verified on the test box: a press to the loopback route paused within the beat, muted at once, and resumed on play.
## 0.9.293 (2026-09-04 10:34 UTC)
kicad_demo progress now reports panel (last show reply, stage, callback URL), muted, muteSource, lastPress and paused; each step in the final result carries foregrounded (whether the beat's window was brought forward once).
## 0.9.292 (2026-09-04 10:30 UTC)
Demo panel: reason is sent on every show (ab marks it required on show; a stage-advance show without it was refused live and the remote stayed at 1/7), and every show's reply is recorded on kicad_demo progress (panel: shown, stage, callbackUrl, error) so a refused show is visible instead of silent.
## 0.9.291 (2026-09-04 10:28 UTC)
kicad_demo adopts the ab 2.1.17 demo-panel contract: the first show passes eventCallbackUrl (loopback POST /demo/event on the bridge's own port) so a press lands the instant it is clicked; mute/unmute silence or replay the beat's narration at once; pause/stop silence at once and apply at the beat boundary; stage-advance shows send only the stage so a user's pause or mute is never undone; the poll stays as backstop and skips presses already delivered. The tour now foregrounds each beat's window exactly once (John: the user must see which window is being demoed, but keeps full control between beats); no persistent focus guardian during the tour. One short ab caption per beat stays.
## 0.9.290 (2026-09-04 09:32 UTC)
kicad_demo drives ab's desktop_demo_panel (Adom Bridge 2.1.0+, wiki adom/adom-bridge#116): the floaty play/pause/next/back/stop remote is shown at stage 0 with the seven stops, polled between beats, stage and state updated per beat, hidden on done/exit/error; the toast transport remains only as the fallback for an older ab. Every beat paints one short ab caption (KiCad tour n/7: ...) for about the beat's length instead of a paragraph for a minute (John, 2026-09-03).
## 0.9.289 (2026-09-03 19:26 UTC)
John, 2026-09-03: no caption on a Symbol Editor launch or rescan reopen (the 0.9.285 one was large, shown too long, and wrong on his laptop: it promised 'behind your window' while KiCad raised itself in front while loading). Launch is silent. _foreground now also reports editorInFrontAtEnd, measured from AD's z-order at return time, so a response never claims background about a window the user can see on top. Dev skill records the rule: one early look, no fighting the user for the foreground, captions only on the opt-in allowFocusSteal path and short.
## 0.9.288 (2026-09-03 19:00 UTC)
Captions before a KiCad window appears now name the calling AI thread (John saw one on his laptop and could not tell which thread was opening the editor). The Symbol Editor close used by rescan goes through ab's desktop_close_window (ab 2.1.12+, graceful, never forced) with the local WM_CLOSE as fallback for older ab; responses say editorCloseVia. Bridge owns KiCad, AD owns Windows (wiki #74 item 3).
## 0.9.287 (2026-09-03 17:58 UTC)
Wiki #71 (Ray, 0.9.286 run): (1) the posted Enter now goes FIRST to the window holding keyboard focus in KiCad's GUI thread (GetGUIThreadInfo), and wxDataView children count as tree candidates regardless of height, so a short Libraries pane no longer yields zero targets; (2) a navigation that ran out of the call budget returns navigation_unconfirmed_within_budget with the trace and _foreground instead of the 'still coming up' contract about an editor that was already driven; (3) an editor the bridge opened after the library file was last written is never judged stale again, so repeated calls stop re-opening it (staleVeto says so); (4) symbol_editor_did_not_open carries pathwaysTried; navigation_failed responses carry errorCode and resolved fields.
## 0.9.286 (2026-09-03 17:05 UTC)
Z-order guard fix: the 0.9.285 guard read AD's window list with the wrong envelope shape and always saw nothing (field test reported 'no window was launched' during a real relaunch). Both the Symbol Editor launch guard and handlers/foreground_guard now read z-order through handlers.kicad_windows, the one parser of AD's desktop_list_windows.
## 0.9.285 (2026-09-03 17:01 UTC)
Foreground etiquette on the Symbol Editor launch (wiki #71 field test): before opening or auto-rescan-relaunching the editor the bridge captions why a KiCad window is about to appear, remembers the user's front window, and the moment the new frame exists looks ONCE at the z-order; if the frame landed above a non-KiCad user window it slides the frame back behind it with SetWindowPos(NOACTIVATE) and then leaves the z-order alone for good (alt-tab and taskbar clicks stay the user's). show_library responses carry _foreground with what happened. kicad_install_symbol success now includes kicadParser (KiCad's verdict on the written file).
## 0.9.284 (2026-09-03 16:44 UTC)
kicad_set_design_rules: response separates fabRuleViolations (DRC items citing one of the fab's rules by name) from otherViolations, and carries drcSummary; the copper layer count is read per layer entry, not per line, so a one-line (layers ...) block no longer infers 1 layer.
## 0.9.283 (2026-09-03 16:38 UTC)
Wiki #73: kicad_list_design_rules and kicad_set_design_rules consume adom/pcb-design-rules at call time (fab, layers, process; layers defaults to the board's copper count; stages <stem>.kicad_dru with backup; runs DRC with it). Wiki #62: kicad_list_symbols (bridge inventory + kicadParser), and kicad_show_library resolves an MPN/file name to the real symbol name (exact, case-insensitive, unique prefix) reporting aliasedFrom/aliasHow. Navigation trace no longer implies the filter was not applied when wx answers WM_GETTEXT with ''. kicad-bridge-dev skill records the #71 lessons.
## 0.9.282 (2026-09-03 16:25 UTC)
Wiki #71 (Ray's remaining case): on a fresh Symbol Editor the filtered tree lists the symbol but nothing is selected, so the posted Enter has nothing to activate and the posted double-click depends on row geometry (DPI). Ray measured select-then-real-Enter loads it. show_library now adds keyboard-only rounds: Down x1..3 posted to the tree candidates, then Enter, title-verified, still PostMessage only (no focus, no foreground). Success responses carry the navigation trace too, so a re-run shows which round landed.
## 0.9.281 (2026-09-03 16:19 UTC)
Wiki #71: kicad_show_library failure responses now carry a per-step navigation trace (search Edit found, parent chain, filter text as read back, tree candidates with class and rect, editor title after Down, after posted Enter, after posted double-click). Ray measured on his box that the tree lists the symbol and a real Enter loads it while the bridge's posted Enter and double-click do not; the trace is how the next build finds which hwnd the Enter must reach.
## 0.9.280 (2026-09-03 16:00 UTC)
kicad_install_symbol now passes errorCode (kicad_refuses_symbol), kicadParser and _hint through to the caller; 0.9.279 set them inside add_symbol but the verb wrapper dropped them, so the wire response had errorCode null.
## 0.9.279 (2026-09-03 15:57 UTC)
Wiki #71 second cause, measured on ConfRoomROG with KiCad's own parser: one malformed symbol makes KiCad refuse a whole .kicad_sym (Symbol Editor lists the library EMPTY) while the bridge's structural reader called it clean. New handlers/kicad_parse_check.py runs kicad-cli sym export svg (read-only) as KiCad's verdict and inventory. kicad_install_symbol and kicad_install_library refuse a file KiCad refuses before writing (kicad_refuses_symbol / kicad_refuses_library); kicad_adom_library_status, kicad_lint_library and the kicad_show_library error carry kicadParser; kicad_adom_library_heal mode:prune drops the symbols KiCad refuses (dryRun names them, original kept as .pruned.bak). Lint's checkmark now says whether KiCad was consulted. Also measured: KiCad's library index is process-wide; a reopened editor frame keeps the old symbol set until kicad.exe fully restarts.
## 0.9.278 (2026-09-03 11:49 UTC)
Wiki #72: kicad_install_library handed a single-part .kicad_sym now returns singlePartFile:true plus a hint naming kicad_install_symbol {filePath}, on both the fresh and already-registered success paths; a real multi-symbol library gets no hint. The verb still does what it did (registers the file as its own library); it just stops being silent about the shared Adom library being untouched.
## 0.9.277 (2026-09-03 02:41 UTC)
kicad_adom_library_status: orphanedLibrary now means the orphan holds symbols the registered file lacks (unique-name compare; new orphanMissingFromRegistered and orphanMissingSample). A count compare kept flagging John's orphan after the 0.9.276 merge because its 122 lenient count included 28 duplicate copies. build_release.py refuses a non-semver first argument (a stray flag was once stamped in as the version).
## 0.9.276 (2026-09-03 02:35 UTC)
heal merge reads a corrupt orphan tolerantly: the orphaned Adom library on a redirected box had 94 symbols inside the library plus 28 duplicate copies appended AFTER the closing paren (the old appender bug's fingerprint), so the strict gate refused the whole file. The heal SOURCE is now read block by block with a quote-aware depth scan, each block balance-checked on its own, duplicates deduped first-copy-wins and reported; the file WRITTEN still goes through the strict gate. Measured on the real file: 94 unique recoverable, 0 unparseable, 28 dupes.
## 0.9.275 (2026-09-03 02:32 UTC)
kicad_adom_library_heal (wiki #71 follow-up, John's call: merge): reconcile a split Adom library by merging every symbol from the orphaned bridge-default file into the registered file KiCad reads, one quote-aware add behind the balance gate with a .bak; dryRun previews; repoint mode kept as the other answer. Never runs on its own. Idempotent, refuses an unbalanced source, never edits or deletes the orphan.
## 0.9.274 (2026-09-03 02:06 UTC)
Wiki #71 root cause: on a OneDrive-redirected Documents the bridge used %USERPROFILE%/Documents while KiCad resolves the shell Documents folder, so the bridge wrote and reported symbols in a file KiCad never reads. Fix: kicad_detect resolves user_dir like KiCad (handlers/win_paths), the Adom symbol and footprint libraries are ROW-FIRST (install writes to the file sym-/fp-lib-table registers), adom_library_status reports registeredPath/bridgeDefaultPath/split/orphanedLibrary, and the library_cache_stale verdict is built from that measurement instead of a cache story (both prior explanations were disproved by Ray).
## 0.9.273 (2026-09-03 01:15 UTC)
Adopt the insiders tier: bridge.json declares insidersManifestUrl, build_release ships to insiders by default and refuses to publish without a changelog, tools/promote.py moves the public manifest only on a human's attestation. Wiki #72 groundwork.
## 0.9.272 (2026-09-02, backfilled)
Wiki #71 (Ray): stop asserting causes the bridge never checked. show_library's
library_cache_stale message claimed the editor indexed before the symbol was
added, which Ray's ordering disproved; it now describes KiCad's PROCESS-WIDE
library cache. The starting contract no longer reports "still coming up" when no
Symbol Editor window exists at all (it reported progress for 12 minutes on a
window that was never created). kicad_rescan_libraries' tree-refresh path no
longer claims parts "are now visible" - an effect it never verified - and returns
verified:false.
## 0.9.271 (2026-09-02, backfilled)
handlers/kicad_windows.py: ONE KiCad window finder replacing six per-module
EnumWindows loops, AD's desktop_list_windows first (carries z-order) with local
enumeration as fallback, 0.25s TTL because a bridge calling AD is re-entrant.
kicad_errors migrated onto it, so dialogs are matched by OWNING EXE instead of by
title. find_project_manager de-duplicated from the two editor modules.
## 0.9.270 (2026-09-02, backfilled)
kicad_screenshot_all captures via AD desktop_screenshot_window (owned popups,
coordMap, auto-pull) with the local PrintWindow kept as fallback; _canvas_probe
stays local because blank-GL-canvas detection needs raw BGRA. kicad_errors reads
TaskDialog text through AD UIA at DISCOVERY time - the previous two-step hand-off
raced and lost the message.
## 0.9.269 (2026-09-02, backfilled)
Documented the three error channels (dialogs, captured stderr, screenshots) and
kept the screenshot loop as the deliberate floor under the other two.
## 0.9.268 (2026-09-02, backfilled)
kicad_errors handles Windows TaskDialogs, whose DirectUI text win32 cannot read.
## 0.9.267 (2026-09-02, backfilled)
kicad_errors: enumerate KiCad error/warning dialogs read-only. KiCad writes no
log file and in GUI mode wxLogError becomes a message box, so the dialogs are
where a failure reason actually lives.
## 0.9.266 (2026-09-02, backfilled)
Capture KiCad's stderr instead of discarding it (launch used stdout/stderr=DEVNULL)
plus KICAD_ENABLE_WXTRACE, and add kicad_log_tail with a byte offset.
## 0.9.265 (2026-09-02, backfilled)
handlers/foreground_guard.py: caption before any action known to foreground, and
a z-order guard with ONE look inside 200ms, then hands off permanently so a user
alt-tabbing to KiCad is never fought.
## 0.9.264 (2026-09-01, backfilled)
PCM verbs resolve KICAD<n>_3RD_PARTY the way KiCad does, via the Windows shell
Documents folder - with OneDrive Known Folder Redirection that is
%USERPROFILE%/OneDrive/Documents, and installing to the wrong one made PCM report
a package installed while no library ever appeared.
## 0.9.263 (2026-09-01, backfilled)
kicad_pcm_install / pcm_list / pcm_uninstall: install a package from a KiCad PCM
repository on disk exactly as the Plugin and Content Manager does, so KiCad's own
dialog lists the result as Installed and registers the library tables itself.
## 0.9.262 (2026-09-01, backfilled)
Netlist and connectivity family: kicad_extract_netlist, trace_net,
find_connections, analyze_connections. Read-only via headless kicad-cli, so they
work with KiCad closed. Closes the largest gap against third-party KiCad MCP
servers, seven of eight of which had netlist tooling this bridge lacked.
## 0.9.261 (2026-09-01, backfilled)
Three-way merge recovering fixes that 0.9.251-0.9.260 had silently reverted (the
quote-aware .kicad_sym parser, demo captions, the #54 sub-node verify) while
keeping Colby's 0.9.251-0.9.260 work intact. Root cause fixed too:
build_release.py pushed only BRIDGE_VERSION/bridge.json/manifest, never the
source it shipped, so the release zip and the page repo disagreed and the next
person to publish from the repo reverted everything.