Commit Graph

348 Commits

Author SHA1 Message Date
Brett Morgan
b140015299 Update package-lock.json
This is the results of running `npm audit fix`
2026-05-01 08:29:24 +10:00
Eugene Mikhantyev
d3c01e20bd Merge pull request #139 from mixelpixx/fix/post-pr88-regressions
Fix two regressions from PR #88 (rotate/mirror)
2026-04-29 21:45:47 +01:00
Eugene Mikhantyev
5907954b3e Fix two regressions from PR #88 (rotate/mirror)
1. add_schematic_net_label failed on schematics with no existing labels.
   The clone-based path required a pre-existing label to copy from;
   the documented "fallback to sexpdata" was a misleading log line —
   the RuntimeError was caught and the call silently returned False.
   Restore hand-built sexpdata construction (without the buggy
   fields_autoplaced token, with orientation-aware justify).

2. get_pin_angle returned the wrong angle for every mirrored symbol
   (off by exactly 180°, all rotations, both mirror axes). The
   mirror_x and mirror_y formulas were swapped relative to the
   pin_world_xy convention — pin_world_xy mirrors a position by
   flipping its local axis component, so the matching angle
   transform is (180 - θ) for mirror_x and -θ for mirror_y.

Add regression tests:
- test_add_label_empty_schematic.py — first label on empty schematic,
  orientation-aware justify.
- test_get_pin_angle.py — full 24-case matrix
  (4 rotations × 3 mirror states × 2 pins).
2026-04-29 21:40:39 +01:00
Eugene Mikhantyev
109ba3f23a Merge pull request #88 from tnemrap/fix/rotate-mirror
Fix/rotate mirror
2026-04-29 21:22:52 +01:00
Tom
41b455c4ca Add Star History section to README
Added Star History section with dynamic chart display.
2026-04-29 15:37:08 +02:00
Michael Parment
a6b4f92e4b fix: stub annotations module and add python/ to sys.path in smoke test
Upstream added `from annotations import AnnotationLoader` and moved
`from commands.wire_manager import WireManager` to module-level in
kicad_interface.py. The smoke test now stubs annotations and ensures
python/ is on sys.path so commands.* imports resolve without installing.
2026-04-28 13:38:12 +02:00
Michael Parment
7cafbda127 fix: get_schematic_pin_locations now accounts for mirror flags
Previously get_pin_location and get_pin_angle read symbol state from a
kicad-skip cache that does not reflect (mirror x/y) tokens written by
rotate_schematic_component. Pin coordinates were always computed as if
the symbol was unmirrored.

Fix:
- Added _get_symbol_transform() which reads position, rotation, mirror_x,
  mirror_y, and lib_id directly from the .kicad_sch file via sexpdata +
  WireDragger.find_symbol (the authoritative source after a rotate/mirror)
- get_pin_location now delegates the full transform (mirror → rotate →
  translate) to WireDragger.pin_world_xy, matching the logic used by
  move_schematic_component and rotate_schematic_component
- get_pin_angle now applies mirror-induced angle reflection before adding
  symbol rotation: mirror_x negates the angle, mirror_y reflects across 180°

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 13:36:29 +02:00
Michael Parment
d53533b322 fix: add_schematic_net_label uses kicad-skip clone() instead of sexpdata
Two bugs fixed:

1. fields_autoplaced yes was always injected — caused incorrect visual
   rendering of label text in KiCAD. Removed by using clone() which
   copies an existing label without that field.

2. (justify left bottom) was hardcoded regardless of orientation.
   For orientation 180/270 KiCAD requires (justify right bottom).
   Now set correctly via new_label.effects.justify._tree[1].

Implementation switches from manual sexpdata list construction to
kicad-skip Schematic.label[0].clone(), which produces a structurally
correct label that KiCAD can round-trip without modification.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 13:33:25 +02:00
Michael Parment
53e656b952 fix: rotate_schematic_component uses sexpdata API and drags wires
Previously the handler used kicad-skip to apply rotation and mirror.
kicad-skip has no API for (mirror x/y) on placed symbols, causing:
  'NoneType' object has no attribute 'value'

Fix:
- Rewrote _handle_rotate_schematic_component to use sexpdata (same
  approach as move_schematic_component) for both rotation and mirror
- Added WireDragger.compute_pin_positions_for_rotation: computes old
  and new pin world positions when rotation/mirror changes at fixed (x,y)
- Added WireDragger.update_symbol_rotation_mirror: updates (at) rotation
  and adds/removes/replaces the (mirror x/y) sexpdata token cleanly
- Connected wires now follow pin positions after rotate/mirror via the
  existing WireDragger.drag_wires infrastructure

Tests: 10 unit tests in tests/test_rotate_schematic_mirror.py covering
update_symbol_rotation_mirror, compute_pin_positions_for_rotation, and
a handler smoke test.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-28 13:32:43 +02:00
Eugene Mikhantyev
f9f8e4f7d6 Merge pull request #137 from mixelpixx/fix/pwr-flag-orphan-wire-anchor
Treat PWR_FLAG anchors as connected in orphan-wire detection
2026-04-26 16:08:31 +01:00
Eugene Mikhantyev
7f3a379657 Treat PWR_FLAG anchors as connected in orphan-wire detection
PWR_FLAG instances use a #FLG reference prefix, not #PWR, so their
pin positions were never registered as virtual connection anchors in
_parse_virtual_connections. As a result, find_orphaned_wires reported
wire ends terminating on a PWR_FLAG as dangling. Other call sites
(schematic_analysis.py:127, kicad_interface.py:3814) already recognize
#FLG as a power symbol; align this site with them.

Also coerce a previously-validated Optional[int] to int in board/layers.py
so the file passes mypy (required by the pre-commit hook); behavior is
unchanged because the value is already None-checked above.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-26 16:05:35 +01:00
Eugene Mikhantyev
a87c4515c5 Merge pull request #136 from mixelpixx/fix/auto-junction-sync-followups
Auto-sync schematic junctions on wire and symbol mutations
2026-04-26 15:43:20 +01:00
Eugene Mikhantyev
193e1a603f Drop research-project disclaimer from CHANGELOG header
The disclaimer is project-stance commentary, not a changelog entry; moved
to local notes outside the repo.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-26 15:28:32 +01:00
Eugene Mikhantyev
f11d453c31 Tidy auto-junction-sync code
- Refactor _handle_rotate_schematic_component to use raw sexp throughout
  and write the schematic once instead of three times
- Hoist sexpdata and WireManager imports to module scope; drop the
  unnecessary underscore aliases in move/rotate handlers
- Move WireManager._SUB_UNIT_RE to the top of the class body
- Promote the per-call Symbol("symbol")/Symbol("unit") allocations in
  _parse_lib_pins / _collect_pin_positions to module-level _SYM_*
  constants
- Document the assumption behind _SUB_UNIT_RE's greedy match

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-26 15:13:47 +01:00
Eugene Mikhantyev
7a6558b9fa Auto-sync junctions on wire/symbol mutations
Replaces the manual add_schematic_junction tool with automatic junction
management. WireManager.sync_junctions inserts/removes junction dots
based on wire endpoints plus component pin positions and is invoked
after add_wire, add_polyline_wire, delete_wire, move, and rotate.

- Pin-aware: parses lib_symbols and applies KiCad's mirror/rotate/
  translate transform to compute world pin coordinates
- Multi-unit safe: filters lib_symbols sub-units by the placed
  symbol's (unit N) field plus the unit-0 common body
- Removes the now-unused WireManager.add_junction static method
- Updates CHANGELOG [Unreleased] with the tool removal notice
- Adds .mcp.json to .gitignore (machine-local paths)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-26 14:59:47 +01:00
mixelpixx
17a2e14e9c Merge pull request #131 from 7tobias/fix/add-layer-kicad9-api
fix(layers): use KiCad 9 API for add_layer
2026-04-26 01:55:24 -04:00
mixelpixx
d957a22144 Merge pull request #125 from daeng5913-create/fix/windows-kicad10-python-path
fix(windows): support KiCad 10.0 pcbnew path (bin/Lib/site-packages)
2026-04-25 19:59:09 -04:00
mixelpixx
b386bc3be5 Merge pull request #130 from 7tobias/feat/delete-trace-wildcard
feat(routing): support '*' wildcard in delete_trace net_name
2026-04-25 19:58:47 -04:00
mixelpixx
c9a98e44be Merge pull request #132 from 7tobias/fix/connect-to-net-pcb-pad-assignment
fix(connect_to_net): also assign net to PCB pad so save_project persi…
2026-04-25 19:13:28 -04:00
Eugene Mikhantyev
c62a859e0b Merge pull request #134 from vdawger/fix/import-time-logging-crash
fix: prevent import-time crash when ~/.kicad-mcp/ is not writable
2026-04-25 23:31:09 +01:00
Eugene Mikhantyev
0efcd923c1 Merge pull request #133 from johndev7000/fix/pin-locator-y-double-negation
fix: remove duplicate Y-axis negation in PinLocator.get_pin_location
2026-04-25 23:29:43 +01:00
Eugene Mikhantyev
9f932b13ef Merge pull request #127 from matthewellis/fix/jlcpcb-downloader-improvements
fix: improve JLCPCB downloader robustness and disk usage
2026-04-25 23:20:10 +01:00
Eugene Mikhantyev
0d5f5ea8a7 Merge pull request #124 from vdawger/fix/schematic-symbol-lookup-libname-ordering
fix: locate placed symbols when (lib_name) precedes (lib_id)
2026-04-25 23:10:51 +01:00
Eugene Mikhantyev
74990eabdf Merge pull request #119 from thesamprice/fix/add-component-subsheet-project-path
fix: resolve project-local sym-lib-table for schematics in sub-folders
2026-04-25 23:06:31 +01:00
Eugene Mikhantyev
86edc58168 Merge pull request #117 from thesamprice/fix/add-label-subsheet-fallback
fix: add_label falls back gracefully on sub-sheet schematics
2026-04-25 23:00:52 +01:00
William Viana
7f473e06cc fix: prevent import-time crash when ~/.kicad-mcp/ is not writable
Configuring logging at module import time hard-failed in environments
without write access to the user's home directory (sandboxed pytest
runners, restricted CI containers, read-only filesystems). The
unhandled OSError/PermissionError aborted module import and cascaded
into ~100 test failures during collection.

Wrap the FileHandler setup in try/except and fall back to console-only
logging when the log directory cannot be created. Production behavior
is unchanged - file logging in ~/.kicad-mcp/logs is still used
whenever the directory is writable.

Also picks up an isort-driven import reorder applied by the project's
pre-commit hook.
2026-04-23 21:24:54 -07:00
John Dev
1c25c85de0 fix: remove duplicate Y-axis negation in PinLocator.get_pin_location
The symbol-to-schematic y-flip was applied twice in sequence (two identical
negation blocks with matching comments), cancelling out and leaving pin
Y-coordinates mirrored about the placement Y. For symmetric passives the
bug is invisible (pin 1 and pin 2 are electrically interchangeable); for
ICs with non-equivalent pins (power pins, opamp inputs, etc.) this causes
tools that go through PinLocator — connect_to_net, add_schematic_connection,
add_schematic_net_label with componentRef+pinNumber — to place connections
at the mirror-flipped pin. Verified against kicad-cli generate_netlist
ground truth: on a Device:R placed at (111.76, 83.82), pin 1 resolves to
y=80.01 (actual) vs y=87.63 (pre-fix).

This is a regression of PR #103, which originally fixed the y-negation;
the redundant second block was added subsequently.

Includes a regression test with both a straight Device:R and a rotated
Device:C to exercise the y-flip + rotation pipeline.
2026-04-23 19:19:14 +01:00
Tobias Welz
3a172f0448 fix(connect_to_net): also assign net to PCB pad so save_project persists it
connect_to_net and connect_passthrough previously only touched the
schematic: a wire stub plus a net label were added via
ConnectionManager, but the corresponding pad on the .kicad_pcb was
never updated.

pcbnew.SaveBoard() silently drops every net that is not referenced by
at least one board element (pad/track/via/zone). A net that exists
only in the schematic therefore disappears on save, and in KiCad the
board's ratsnest never shows anything.

Fix:
- new _assign_net_to_pad(component_ref, pin_name, net_name):
  ensures the net exists on the board (creates NETINFO_ITEM if not)
  and sets it on the matching pad of the matching footprint.
- _handle_connect_to_net calls it after the schematic op when
  self.board is loaded.
- _handle_connect_passthrough parses ConnectionManager's 'connected'
  entries ('J1/1 <-> J2/1 [PIN_1]') and assigns nets to both pads.
- register 'connect_to_net' in _BOARD_MUTATING_COMMANDS so the
  existing auto-save path persists the pad assignment to disk.
2026-04-23 14:07:59 +02:00
Tobias Welz
b19d341daf feat(routing): support '*' wildcard in delete_trace net_name
Passing net_name='*' now deletes all tracks on the board (respecting
the include_vias flag). Useful for wiping a test layout before
re-routing without having to iterate every net by name.
2026-04-23 14:04:21 +02:00
Tobias Welz
5ae4bc11c9 fix(layers): use KiCad 9 API for add_layer
board.GetLayerStack() was removed in KiCad 9. Call SetLayerName and
SetLayerType directly on the board instead, and grow the copper layer
count via SetCopperLayerCount when adding inner layers. Without this,
add_layer raises AttributeError on any KiCad 9 installation.
2026-04-23 14:01:27 +02:00
Matthew Ellis
985fca108e style: add return type hints to all function signatures
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 03:04:09 +01:00
Matthew Ellis
7b6d327688 fix: improve JLCPCB downloader robustness and disk usage
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-23 02:56:43 +01:00
mixelpixx
a8684a1f97 Add link to official forum in README 2026-04-22 14:14:24 -04:00
mixelpixx
00c3eb9dd2 Revise forum link and add help section
Updated forum link and added a help section.
2026-04-22 09:18:39 -04:00
mixelpixx
92419dba2e Update README with new forum link
Added a note about the new forum for community discussions.
2026-04-22 09:16:55 -04:00
mixelpixx
a3ee609742 Add announcement for new forum in README 2026-04-22 09:15:30 -04:00
TE603
1a14a45881 fix(windows): add KiCad 10.0 bin/Lib/site-packages to Python path detection
KiCad 10.0 on Windows ships pcbnew.py under bin/Lib/site-packages rather
than the lib/python3/dist-packages path used by KiCad 9.x. Without this
path the MCP server's Python process fails to import pcbnew and exits
immediately with "Failed to import pcbnew module - KiCAD Python API not found".

Changes:
- Prioritise 10.0 in the version list so the newer path is checked first
- Add bin/Lib/site-packages check before the existing lib/python3/dist-packages
  check for every version, so both layouts are supported side-by-side

Note: the pcbnew extension is compiled against KiCad's bundled Python 3.11,
so callers must also set KICAD_PYTHON to the KiCad python.exe
(C:\Program Files\KiCad\10.0\bin\python.exe) to avoid a DLL version
conflict when the system Python differs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-22 16:00:43 +09:00
William Viana
e96637c6c3 fix: locate placed symbols when (lib_name) precedes (lib_id)
KiCad serialises rescued or locally-customised library entries with an
extra (lib_name "...") child before (lib_id "..."):

    (symbol
      (lib_name "RESISTOR_0603_4")
      (lib_id "MF_Passives:RESISTOR_0603")
      (at 132.08 44.45 90)
      ...)

The block-matching regex in _handle_get_schematic_component,
_handle_edit_schematic_component, and _handle_delete_schematic_component
required (lib_id IMMEDIATELY after (symbol, so any placed component
using this form was silently invisible to lookup. The user-visible
symptom is "Component '<ref>' not found in schematic" even though the
component is plainly present (and reachable through list / IPC paths).
This bug also affected set/remove_schematic_component_property and the
existing footprint/value/reference rewriting paths in edit, since they
all share the same lookup code.

The parent-position lookup used a similarly-strict regex
((symbol (lib_id "...") (at ...))), which silently fell back to (0,0)
on (lib_name)-first symbols and caused new properties added through
the custom-properties path to anchor at the schematic origin instead
of the parent symbol.

Fix: relax the symbol-block opening pattern to (symbol\s+\( — matching
any opening paren after (symbol — and read the symbol's origin from
the first (at ...) inside the block. Library-definition entries inside
(lib_symbols ...) are still excluded by the existing range check
(they use the (symbol "name" ...) form with a quoted string, not a
paren).

Adds 7 regression tests in TestLibNameBeforeLibIdOrdering using a
real-world (lib_name)-first resistor block, covering get / edit /
set-property / remove-property / delete and verifying that newly
added properties anchor to the symbol origin instead of (0, 0).
2026-04-21 10:12:52 -07:00
mixelpixx
28d9f3353e Merge pull request #115 from thesamprice/test/add-schematic-component-unit
test: add unit parameter tests for add_schematic_component
2026-04-21 09:15:59 -04:00
mixelpixx
738f652eab Merge pull request #118 from thesamprice/fix/delete-label-all-types
fix: delete_label matches global_label and hierarchical_label types
2026-04-21 09:01:27 -04:00
mixelpixx
1b2b98fd45 Merge pull request #116 from thesamprice/feat/ipc-annotation-generator
feat: Claude-powered annotation generator for KiCad IPC API tools
2026-04-21 09:00:49 -04:00
mixelpixx
4d8dcf7dbb Merge pull request #103 from tecnovel/main
fix: correct pin location, symbol reference dedup, and ERC violation parsing
2026-04-21 09:00:09 -04:00
mixelpixx
74b4e717f8 Merge pull request #120 from thesamprice/feat/hierarchical-sync
feat: walk all sub-sheets to build hierarchical pad→net map for sync_schematic_to_board
2026-04-21 08:59:39 -04:00
mixelpixx
34feb5dcce Merge pull request #122 from vdawger/feat/multi-sheet-net-connectivity
feat: multi-sheet net connectivity + sexp-based parsing reliability
2026-04-21 08:58:51 -04:00
mixelpixx
cd6f9af366 Merge pull request #123 from vdawger/feat/schematic-component-custom-properties
feat: support arbitrary custom properties on schematic components
2026-04-21 08:58:05 -04:00
William Viana
4d7843c03a feat: support arbitrary custom properties on schematic components
Promotes BOM / sourcing fields (MPN, Manufacturer, DigiKey_PN, LCSC,
JLCPCB_PN, Voltage, Tolerance, Dielectric, ...) to first-class citizens
on placed schematic symbols.

New MCP tools:
- set_schematic_component_property: add or update one custom property
  on a component (convenience wrapper around edit_schematic_component).
- remove_schematic_component_property: delete one custom property.
  The four built-in fields (Reference, Value, Footprint, Datasheet) are
  protected and rejected.

edit_schematic_component enhancements:
- New `properties` parameter: map of property name to either a string
  value or a full spec object { value, x?, y?, angle?, hide?, fontSize? }.
  Adds the property when missing, otherwise updates the existing field
  (and optionally its label position / visibility). Lets a single tool
  call attach an entire BOM payload to a component.
- New `removeProperties` parameter: list of custom property names to
  delete in the same call.
- Property values are now backslash-escaped so descriptions containing
  a double-quote or a backslash no longer corrupt the .kicad_sch file.
- New properties default to (hide yes) so they appear in BOM exports
  without cluttering the schematic canvas.

get_schematic_component description clarified to highlight that it
already returns every field on the symbol, including custom ones.

New MCP prompt component_sourcing_properties guides agents through the
conventional property names recognised by downstream BOM tooling and
the recommended call sequence.

Implementation (python/kicad_interface.py):
- _PROTECTED_PROPERTY_FIELDS frozenset
- _escape_sexpr_string / _find_matching_paren static helpers
- _set_property_in_block / _set_hide_on_property /
  _remove_property_from_block surgical text-level edits that preserve
  formatting and the property's UUID
- _handle_edit_schematic_component rewritten to orchestrate
  add/update/remove and return a per-property summary
- New handlers _handle_set_schematic_component_property and
  _handle_remove_schematic_component_property registered in the
  command dispatch table

Tests (tests/test_schematic_component_properties.py):
32 tests covering escape helper, paren matcher, add/update/remove
(single + batched), full spec dicts, default position, default
(hide yes), special-character escaping, UUID preservation, protected
built-in field rejection, no-op removal, both new convenience tools,
and input validation. All 590 tests in the project still pass.

Docs: README, SCHEMATIC_TOOLS_REFERENCE, TOOL_INVENTORY, CHANGELOG.
2026-04-20 17:36:38 -07:00
William Viana
046f33d876 feat: multi-sheet net connectivity + sexp-based parsing reliability
Adds robust multi-sheet (hierarchical) net connectivity for KiCad
schematics and switches the wire/label parsing to a direct sexpdata
pipeline that bypasses kicad-skip's collection iteration, which was
silently dropping wires, labels, and symbol instances on real-world
schematics.

python/commands/wire_connectivity.py
  - New sexpdata helpers: _load_sexp, _parse_wires_sexp,
    _parse_labels_sexp, _parse_symbol_instances_sexp,
    _parse_hierarchical_labels_sexp, _discover_sub_sheets.
  - _build_adjacency now detects T-junctions (endpoint landing on
    another wire's interior segment) so adjacency captures connections
    KiCad doesn't represent as separate wire segments.
  - _find_connected_wires gains an interior-segment fallback so labels
    placed mid-wire still seed BFS correctly.
  - _parse_virtual_connections gathers label / global_label /
    hierarchical_label and power-symbol pin positions, with a
    kicad-skip fallback for unit tests that mock the schematic.
  - _find_pins_on_net rebuilds pin positions from sexpdata symbol
    instances (with mirror_x/mirror_y/rotation handling) and uses a
    plus/minus 1 IU tolerance for floating-point edge cases.
  - get_connections_for_net walks the top sheet plus every recursively
    discovered sub-sheet, deduping pins across sheets.

python/commands/pin_locator.py
  - lib_id matching now falls back to a bare-name + unit-suffix match
    so instances like "stat-tis-custom:BAT_18650" resolve to
    lib_symbols entries like "BAT_18650_3".
  - Pin position math now y-negates lib_symbols coords, applies
    mirror_x/mirror_y in local coords before rotation, and propagates
    the same transform into get_pin_orientation so downstream callers
    get a correct outward angle for mirrored symbols.

python/commands/connection_schematic.py
  - generate_netlist now collects nets from both label and
    global_label and routes them through get_connections_for_net so
    netlists reflect cross-sheet connectivity instead of single-sheet
    label-only nets.

python/kicad_interface.py
  - list_schematic_nets aggregates net names across the top sheet and
    all sub-sheets via the sexp helpers, then resolves connections
    using get_connections_for_net.
  - get_net_connections delegates to get_connections_for_net for
    consistent multi-sheet results.
2026-04-20 15:59:22 -07:00
Noah Piqué
ef42eb60bb fix: correct pin location calculation and symbol reference dedup in kicad-skip
Three bugs fixed in the schematic component and pin locator pipeline:

1. component_schematic: remove redundant symbol.append() after clone()
   kicad-skip's clone() already inserts the raw element into the schematic
   tree. The subsequent NamedCollection.append() detects the reference as
   already registered (from the elementRename triggered by setting
   property.Reference.value) and renames it "R1_" with a trailing
   underscore, causing all subsequent pin lookups to fail.

2. pin_locator: negate lib y coordinate before rotation
   lib_symbols in .kicad_sch use library y-up convention; schematic
   coordinates use y-down. get_pin_location now negates pin_rel_y before
   applying rotation, matching KiCad's own transform order (same approach
   as _transform_local_point in schematic_analysis.py).

3. pin_locator: add .rstrip("_") guard in all symbol reference lookups
   Defensive guard against any residual cases where kicad-skip writes a
   trailing underscore to the Reference property value.

Also fixes the self-test script to use template_with_symbols.kicad_sch
(which contains placed _TEMPLATE_* symbols) rather than the expanded
template (which only contains lib_symbols definitions and has no cloneable
instances).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-20 13:10:47 +02:00
Eugene Mikhantyev
5b7434fdef Merge pull request #121 from mixelpixx/feat/schematic-text-tools
feat: add add_schematic_text and list_schematic_texts tools
2026-04-19 23:14:33 +01:00
Eugene Mikhantyev
e5916005a0 feat: add add_schematic_text and list_schematic_texts tools
Adds two new MCP tools for working with free-form text annotations
(SCH_TEXT elements) in KiCad schematics:

- add_schematic_text: place a text note with optional angle, font size,
  bold/italic, and justification
- list_schematic_texts: list all text annotations with optional
  case-insensitive substring filter

Includes WireManager.add_text / list_texts using _text_insert + sexpdata,
handler dispatch in KiCADInterface, TypeScript tool definitions, registry
entry, reference doc updates, and 30 unit tests.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-19 21:26:39 +01:00