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>
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>
Mechanical application of the `.gitattributes` rules from the prior commit.
All 50 files differ only in line endings — verified by
`git diff --cached --ignore-all-space` being empty.
Before: main had 42 CRLF + 27 LF Python files plus mixed-ending in YAML,
templates, and shell scripts. After: every text file is LF (except the
Windows-native *.ps1, *.bat scripts which remain CRLF per gitattributes).
This eliminates the noisy-diff failure mode seen in PR #102, where a
small logic change produced a 918-line diff due to whole-file CRLF→LF
conversion.
Add type annotations to all previously untyped functions and remove 9
suppressed error codes (call-arg, assignment, return-value, operator,
has-type, dict-item, misc, list-item, annotation-unchecked) by fixing
the underlying type issues.
Add [[tool.mypy.overrides]] with ignore_missing_imports for KiCAD-specific
modules (pcbnew, sexpdata, skip, cairosvg, kipy, PIL) so the pre-commit
mypy hook passes in its isolated venv. Add types-requests and pytest to
additional_dependencies in .pre-commit-config.yaml.
Also fixes several real bugs uncovered by stricter checks: incorrect static
calls to instance methods in swig_backend, wrong return type on get_size,
missing value param in BoardAPI.place_component, variable shadowing in
kicad_process.py, unqualified LibraryManager reference in kicad_interface,
and missing top-level Path import.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add isort configuration (profile=black, line_length=100) to pyproject.toml,
add isort pre-commit hook, and auto-sort imports across all Python source files.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add [tool.black] config to pyproject.toml and Black hook to
.pre-commit-config.yaml (rev 26.3.1), then auto-format all Python
source and test files with line-length=100, target-version=py310.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace /home/chris/... absolute paths with Path(__file__)-relative
equivalents in wire_manager.py and pin_locator.py so the test
scripts work on any machine.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- add_schematic_net_label: warn in description that coords must be exact pin endpoints; recommend connect_to_net instead
- connect_to_net: stub wire direction now follows pin angle (was hardcoded +X)
- pin_locator.py: add get_pin_angle() and _get_lib_id() helpers
- new tool: get_schematic_pin_locations(schematicPath, reference) → returns exact x/y of every pin endpoint, so Claude can place labels correctly
- 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
Phase 1 critical fixes addressing three high-priority issues:
Issue #36 - Windows IPC backend crash (os.getuid not available):
- Add platform detection to skip Unix-specific socket paths on Windows
- Use hasattr check before calling os.getuid()
- Windows now uses auto-detect fallback (named pipes)
- Maintains full Unix socket support on Linux/macOS
Issue #37 - Windows schematic file creation broken:
- Generate unique UUIDs instead of invalid all-zeros UUID
- Add explicit UTF-8 encoding for cross-platform compatibility
- Force Unix line endings (LF) to prevent Windows CRLF issues
- Update template file with valid placeholder UUID
- Fix hardcoded /tmp/ paths in wire_manager.py and pin_locator.py
Issue #35 - JLCPCB download limited to 100 parts:
- Change batch_size from 1000 to 100 to match tscircuit API limit
- Remove premature loop termination when batch < batch_size
- Add documentation explaining API limitation
- Expected result: Full ~2.5M part catalog download (40-60 minutes)
All changes maintain backward compatibility and include detailed comments.
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Updates MCP handlers to use the new wiring infrastructure:
Handler Updates:
- _handle_add_schematic_wire: Uses WireManager.add_wire() with S-expression manipulation
- _handle_add_schematic_connection: Uses ConnectionManager with automatic pin discovery and routing options (direct, orthogonal_h, orthogonal_v)
- _handle_add_schematic_net_label: Uses WireManager.add_label() with support for label types and orientation
Features:
- Automatic pin location discovery with rotation support
- Professional wire routing (direct, orthogonal horizontal-first, orthogonal vertical-first)
- Net label placement with customizable types (label, global_label, hierarchical_label)
- Comprehensive error handling and logging
Testing:
- All MCP handlers tested and verified working
- Integration test: 100% passing (2 wires, 1 label created successfully)
- Verified with kicad-skip that wires and labels are correctly formed
Part of Issue #26 schematic wiring implementation (Phase 1)
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>