Move all Python test files from python/tests/ to the top-level tests/
directory to match the project's CONTRIBUTING.md guidelines. Update
sys.path inserts and template path references to reflect the new
location.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Previously passing mirror='x' or mirror='y' to rotate_schematic_component
always raised:
'NoneType' object has no attribute 'value'
Root cause: kicad-skip has no API for setting (mirror x/y) on a placed
symbol instance. The handler tried to use a non-existent kicad-skip
attribute, returning None, then calling .value on it.
Fix: add _apply_mirror_to_symbol_sexp() which directly patches the
(mirror x/y) S-expression token in the .kicad_sch file. The rotate
handler now applies rotation via kicad-skip (which works fine) and
delegates mirror to this helper.
The helper:
- Inserts (mirror x/y) immediately after the (at x y rot) token
- Removes any existing mirror token before inserting the new one
(prevents duplicate tokens when toggling axis)
- Returns False gracefully when the reference is not found
Tests: 6 unit tests in tests/test_rotate_schematic_mirror.py
covering: add x, add y, remove, replace, unknown ref, no-mirror smoke test.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Previously the path argument to create_schematic() was accepted by the
tool schema but silently ignored in SchematicManager.create_schematic()
(python/commands/schematic.py). The schematic file was always written
using only the bare filename, resolving to the MCP server's working
directory.
On systems where that directory is not writable (e.g. Program Files,
OneDrive-synced folders) this caused:
[Errno 13] Permission denied: 'myproject.kicad_sch'
Fix:
- Add path: Optional[str] = None parameter to SchematicManager.create_schematic()
- Compute output_path as os.path.join(path, base_name) when path is given
- Forward the resolved path from _handle_create_schematic() into create_schematic()
Tests: added tests/test_create_schematic_path.py with three unit tests
covering: path respected, no-path fallback, and no double-suffix on .kicad_sch names.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The PR added a second server.tool("move_schematic_component", ...) at line 1127
without removing the original registration at line 722, causing the server to
fail on startup with "Tool move_schematic_component is already registered".
Also adds tests/test_ts_tool_registry.py which scans all src/tools/**/*.ts files
for duplicate server.tool() names so this class of bug is caught automatically.
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>