* Fix: IPC rotate_component now uses absolute angle as documented
The IPC rotate handler was adding the angle to the current rotation
(relative), but the schema documents it as absolute. This caused
unexpected behavior where setting angle=0 had no effect on a component
already at 180°. Now correctly sets the rotation to the exact angle
specified, matching the SWIG backend behavior.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs(changelog): add unreleased entry for rotate_component absolute-angle fix
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
query_traces silently omits PCB_ZONE_T objects, so layer-usage audits
miss power planes and GND pours entirely. query_zones complements it by
iterating board.Zones() and returning each zone's net, layers, priority,
fill state, min thickness, bounding box, and filled area, with the same
net/layer/boundingBox filter surface as query_traces.
search_symbols, list_symbol_libraries, list_library_symbols, and
get_symbol_info previously only consulted the global sym-lib-table. A
library registered with project scope (an entry in
<project>/sym-lib-table) was therefore invisible — even right after
open_project succeeded — making add_schematic_component the only tool
that could see it.
Fix has two parts:
1. Wrap project_commands.open_project and project_commands.create_project
in handlers that rebuild SymbolLibraryCommands.library_manager against
the project directory. After open_project, project-scope libraries are
automatically visible to subsequent search/list/info calls.
2. Add an optional projectPath parameter to the four discovery tools
(accepts a project directory, .kicad_pro, .kicad_pcb, or .kicad_sch
path). Stateless callers can resolve project libraries without first
calling open_project. SymbolLibraryCommands._derive_project_path also
walks up from schematicPath/boardPath to find the directory that owns
the project, mirroring the logic in _handle_add_schematic_component.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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>
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>
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).
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.
Add Prettier as a dev dependency with .prettierrc.json config and
.prettierignore. Hook added via mirrors-prettier in pre-commit config.
All TypeScript, JSON, Markdown, and YAML files auto-formatted.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
PROBLEM
-------
Upstream commit b98c94b added 7 comment lines (;; PASSIVES, ;; SEMICONDUCTORS,
;; INTEGRATED CIRCUITS, ;; CONNECTORS, ;; POWER/REGULATORS, ;; MISC,
;; TEMPLATE INSTANCES) to template_with_symbols_expanded.kicad_sch.
KiCAD's S-expression parser does NOT support any comment syntax.
It expects every non-empty line to begin with '('. These comments caused
KiCAD 9 to refuse opening any schematic generated from this template:
Expecting '(' in <file>.kicad_sch, line 8, offset 5
AFFECTED USERS
--------------
Any project whose .kicad_sch was generated by the MCP server after upstream
commit b98c94b and before this fix contains the same invalid lines. Those
files must be repaired manually: open the .kicad_sch in a text editor and
delete every line beginning with ';;'.
FIX
---
Remove all 7 ;; lines from the template. No functional change — the comments
provided no information that is not already evident from the symbol names.
ALSO
----
CHANGELOG: add critical bug-fix entry for this regression under v2.2.2-alpha
Bug 1 - add_schematic_component: footprint parameter silently ignored
The footprint value from MCP params was never passed through to
DynamicSymbolLoader.add_component() / create_component_instance().
Every placed symbol had an empty Footprint field regardless of input.
Fix: added footprint: str='' to both functions, passed through all
call sites, added footprint to schematic.ts tool schema.
Bug 2 - delete_schematic_component: only deleted first duplicate
When a reference appeared multiple times (e.g. after a failed
add attempt), only the first instance was removed due to break
after first match. Fix: collect all matching blocks first, then
delete back-to-front to preserve indices. Response now includes
deleted_count.
New tool - edit_schematic_component
Update footprint, value or reference of a placed symbol in-place.
More efficient than delete+re-add: preserves position and UUID.
Accepts: schematicPath, reference, footprint?, value?, newReference?
All 3 fixes verified by live tests on a real JLCPCB/KiCAD 9 project:
- R_TEST1: footprint Resistor_SMD:R_0603_1608Metric written correctly
- J1 duplicate: deleted_count=2 with single call
- J2 edit: PinSocket footprint assigned in-place, no delete+add needed
- PCB update (F8) confirmed: only components with footprint imported
Verified by live test: created a fresh schematic via MCP, result shows
format version 20250114, 0 _TEMPLATE_ hits, 0 (lib_id -100) hits, 24
real components placed cleanly.
--- Format version bump (20230121 KiCAD 7 -> 20250114 KiCAD 9) ---
Files: python/templates/*.kicad_sch, python/commands/project.py,
python/commands/schematic.py
Root cause: the MCP server targets KiCAD 9 exclusively - pcbnew.pyd is
compiled for KiCAD 9.0 / Python 3.11.5, and server.ts explicitly selects
the KiCAD 9 bundled Python on Windows. Generating new schematics with a
2-year-old format tag caused a spurious 'This file was created with an
older KiCAD version' warning on every newly created schematic.
--- Remove corrupt _TEMPLATE_* placed-symbol blocks ---
File: python/templates/template_with_symbols_expanded.kicad_sch
Root cause: the expanded template was generated by the old sexpdata
serializer (same corruption PR #40 fixed for DynamicSymbolLoader add-path).
The serializer converted the string 'Device:R' to integer -100, producing
(lib_id -100) instead of (lib_id Device:R). KiCAD cannot resolve an
integer as a library reference and crashes with a null-pointer when the
user attempts to select these symbols. They appeared as grey _TEMPLATE_R?,
_TEMPLATE_C?, _TEMPLATE_U_REG? etc. ~5000mm off-sheet - invisible during
normal work but triggering a crash on accidental box-select.
Discovered via live testing on a real JLCPCB/KiCAD 9 project.
New tools - datasheet:
- get_datasheet_url: construct LCSC datasheet PDF URL + product page URL
without any API key (URL schema: https://www.lcsc.com/datasheet/<C#>.pdf)
- enrich_datasheets: scan .kicad_sch, write LCSC datasheet URL into every
symbol that has an LCSC property but an empty Datasheet field; supports
dry_run=true for preview; text-based implementation (no skip writes)
Implementation: python/commands/datasheet_manager.py
New tool - schematic:
- delete_schematic_component: remove a placed symbol from a .kicad_sch file
by reference designator (e.g. R1, U3)
Bug fix - delete_schematic_component (two separate root causes):
1. No MCP tool named delete_schematic_component was registered at all.
Any delete-symbol request fell through to the PCB-only delete_component
tool which searches pcbnew.BOARD and always returned 'Component not found'
for schematic symbols.
2. component_schematic.py::remove_component() still used skip for writes.
PR #40 rewrote DynamicSymbolLoader (add path) to avoid skip-induced
schematic corruption, but the delete path was not touched by that PR.
Fix: _handle_delete_schematic_component in kicad_interface.py uses direct
text manipulation with parenthesis-depth tracking (same technique as PR #40),
bypassing component_schematic.py entirely. Error message explicitly guides
users: 'use delete_component for PCB footprints'.
Files changed:
- python/commands/datasheet_manager.py (new)
- src/tools/datasheet.ts (new)
- python/kicad_interface.py: 3 new handlers + dispatch entries
- src/tools/schematic.ts: delete_schematic_component tool
- src/server.ts: registerDatasheetTools import + call
- src/tools/index.ts: export registerDatasheetTools
- CHANGELOG.md: document all above
- connection_schematic.py: generate_netlist() now accepts schematic_path param,
threaded through to get_net_connections() so PinLocator is actually invoked
(previously only 1 connection per component was returned due to fallback break)
- kicad_interface.py: pass schematic_path to generate_netlist()
- pin_locator.py: add _schematic_cache to avoid loading Schematic() once per pin
(was causing timeout: O(nets x components x pins) Schematic() calls)
- server.ts: remove fragile PYTHONPATH?.includes('KiCad') condition,
always prefer KiCAD bundled Python on Windows when executable exists
- CHANGELOG.md: document fixes under v2.2.0-alpha
Comprehensive documentation of Phase 2 achievements including power symbol support, wire graph analysis for net connectivity, critical bug fixes (template mapping, special character handling), and 100% passing integration tests. Removes emoji per style guidelines.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Documentation Updates:
- README: Updated Schematic Design section from 6 to 9 tools
- Added "Wiring & Connections" subsection highlighting new capabilities
- Documented automatic pin discovery with rotation support
- Listed smart routing options (direct, orthogonal)
- Added net label management features
- CHANGELOG: Added Phase 1 wiring system entry with complete feature list
New Features Documented:
- add_schematic_connection with auto pin discovery
- add_schematic_net_label with orientation control
- WireManager and PinLocator implementation
- S-expression precision and format compliance
Part of Issue #26 schematic wiring implementation
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>