Commit Graph

221 Commits

Author SHA1 Message Date
Michael Parment
01011487d0 fix: merge upstream type annotations into create_schematic signature
Combined our path parameter fix with upstream's type annotation additions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-08 10:43:13 +02:00
Michael Parment
b3ca93a98d fix: create_schematic now respects the path parameter
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>
2026-04-08 10:27:53 +02:00
Eugene Mikhantyev
227433716a Merge pull request #86 from mixelpixx/fix/enable-import-untyped-mypy
chore: enable strict mypy checks and fix real bugs uncovered
2026-04-06 21:28:27 +01:00
Eugene Mikhantyev
9b1024a8f3 chore: enable strict mypy checks and fix pre-commit mypy hook
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>
2026-04-05 23:50:54 +01:00
Eugene Mikhantyev
5a2b481db3 chore: remove mypy overrides now that venv uses system-site-packages
With --system-site-packages, mypy can resolve pcbnew, skip, and sexpdata
directly from the system/venv, so per-module ignore_missing_imports
overrides are no longer needed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-05 21:30:50 +01:00
Eugene Mikhantyev
c0630c2b64 chore: remove unused mypy overrides for cairosvg, kipy, schematic
These packages are not imported anywhere in the codebase, so their
ignore_missing_imports overrides were unnecessary.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-05 21:26:05 +01:00
Eugene Mikhantyev
5d1477f548 chore: enable import-untyped and import-not-found mypy checks
Remove global ignore_missing_imports and the import-untyped disable,
replacing them with targeted per-package overrides for third-party
libraries that lack stubs (pcbnew, skip, sexpdata, cairosvg, kipy,
schematic). Also add python/ to mypy_path so internal modules resolve.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-05 21:24:00 +01:00
Eugene Mikhantyev
f9875ab617 Merge pull request #85 from vdawger/fix/extend-timeout-schematic-queries
fix: extend timeout for schematic query commands on large files
2026-04-05 20:20:39 +01:00
William Viana
c43784cd78 fix: extend timeout for schematic query commands on large files
Add list_schematic_nets, list_schematic_labels, and get_schematic_view
to the longRunningCommands list so they use the 10-minute timeout
instead of the default 30 seconds. These commands regularly exceed
the 30s limit on larger schematic files.
2026-04-05 09:33:29 -07:00
mixelpixx
25f856024c Merge pull request #83 from vdawger/fix/stdout-pollution-timeout
fix: prevent pcbnew stdout noise from causing sync_schematic_to_board timeouts
2026-04-04 14:34:19 -04:00
William Viana
0bc00b1451 fix: prevent pcbnew stdout noise from causing sync_schematic_to_board timeouts
The TS<->Python communication channel uses stdout for JSON responses.
pcbnew's C++ SWIG layer can write warnings and diagnostics directly to
C-level stdout (fd 1), corrupting the JSON framing. The TS parser then
never sees valid JSON and the command times out after 30 seconds.

Three changes fix this:

1. Python stdout redirect: In main(), save the original stdout fd for
   exclusive JSON response use, then redirect fd 1 to stderr so all
   pcbnew C++ output goes to logs instead of the response pipe.

2. Robust TS JSON parser: tryParseResponse() now uses newline-delimited
   parsing as a fallback. The Python side writes single-line JSON
   terminated by \n; the parser uses this as the completion signal
   instead of brace-matching, which prevents premature resolution of
   truncated chunked responses. Non-JSON preamble lines are logged
   and stripped.

3. Fix stray print() calls: Converted print() to logger in
   component_schematic.py and library_schematic.py so they don't
   leak to stdout during normal operations.

Also adds sync_schematic_to_board to the longRunningCommands list for
an appropriate timeout value.
2026-04-03 11:24:42 -07:00
Eugene Mikhantyev
f79a3d6435 Merge pull request #65 from Mehanik/feat/move-component-wire-preservation
feat: move_schematic_component with wire preservation (drag behavior)
2026-03-29 23:56:00 +01:00
Eugene Mikhantyev
25e81b6411 refactor: move move_schematic_component registration back to original position
Restore the tool registration order so move_schematic_component appears
before rotate_schematic_component, matching the pre-PR location.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 23:54:29 +01:00
Eugene Mikhantyev
c4f013e6c7 fix: remove duplicate move_schematic_component tool registration and add regression test
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>
2026-03-29 23:45:21 +01:00
Eugene Mikhantyev
d58283ef0a feat: synthesize wires for touching-pin connections on component move
When moving a schematic component whose pins directly touch pins of
stationary components (no wire segment, just pin-to-pin contact),
synthesize bridge wires to preserve the electrical connection after
the move. Also fixes duplicate-pin-position collision in old_to_new
map and updates symbol reference assignment to use setAllReferences.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 23:41:42 +01:00
Eugene Mikhantyev
a152b75db3 feat: move_schematic_component with wire preservation (drag behavior)
When moving a schematic component, connected wires are stretched/shifted
to follow the component (like KiCAD's drag behaviour), preserving
connectivity instead of leaving dangling wire stubs.

Also fixes property labels (value, reference, etc.) so they shift with
the symbol rather than staying at their original positions.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 20:34:22 +01:00
mixelpixx
74471ce72e Merge pull request #81 from mixelpixx/setup-pre-commit
chore: set up pre-commit hooks to enforce CONTRIBUTING.md code style rules
2026-03-29 10:08:49 -04:00
Eugene Mikhantyev
f39937e8b8 fix: use local prettier from package.json and clean up prettierignore
- Replace mirrors-prettier alpha (v4.0.0-alpha.8) with local hook using
  the stable prettier installed via package.json
- Remove .prettierignore entries already handled by the hook's exclude pattern

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 13:35:26 +01:00
Eugene Mikhantyev
bc1e33b652 fix: resolve pre-commit hook issues for mypy and root-level files
- Fix mypy duplicate module conflict by excluding python/commands/board.py
- Add import-untyped to mypy disabled error codes
- Use explicit_package_bases for proper module resolution
- Auto-format root-level download_jlcpcb.py and test-router.js

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 13:21:05 +01:00
Eugene Mikhantyev
dbbbde17ba chore: add ESLint with TypeScript support and baseline config
Install eslint, @eslint/js, and typescript-eslint as dev dependencies.
Add eslint.config.js (flat config) with rules tuned to zero errors on
the current codebase, add ESLint local hook to .pre-commit-config.yaml,
and update the lint:ts npm script to use ESLint directly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 13:15:15 +01:00
Eugene Mikhantyev
3456a1df26 chore: add MyPy type checking config with baseline ignore rules
Adds [tool.mypy] section to pyproject.toml with permissive baseline settings
and disables error codes that fire against the existing untyped codebase.
Adds the mirrors-mypy pre-commit hook (v1.19.1) running over python/ at once.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 13:10:03 +01:00
Eugene Mikhantyev
fc70a4785c chore: add Flake8 linting config with baseline ignore rules
Adds .flake8 config and registers the flake8 pre-commit hook scoped to
python/ at rev 7.3.0. Baseline ignore rules (E501, F401, F541, F841,
E722, E402, E741, F811, F821, F824, E231) suppress existing violations
so the hook passes cleanly on the current codebase.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 13:07:39 +01:00
Eugene Mikhantyev
7d50fa1d4c style: apply Prettier formatting to TS/JS/JSON/MD files
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>
2026-03-29 13:05:50 +01:00
Eugene Mikhantyev
c44bd9205d style: sort Python imports with isort
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>
2026-03-29 13:02:24 +01:00
Eugene Mikhantyev
75cead0860 style: apply Black formatting to all Python files
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>
2026-03-29 13:01:08 +01:00
Eugene Mikhantyev
eee5bfb9ed chore: set up pre-commit framework with general hooks
Add .pre-commit-config.yaml with pre-commit-hooks v5.0.0 (trailing
whitespace, end-of-file fixer, yaml/json checks, large file guard,
merge conflict detection). Add minimal pyproject.toml. Auto-fix
trailing whitespace and missing end-of-file newlines across the
codebase.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 12:58:36 +01:00
Eugene Mikhantyev
41ae1ba82c Merge pull request #80 from mixelpixx/fix/symbol-constants-and-paths
fix: symbol constants and hardcoded path cleanup
2026-03-29 12:41:17 +01:00
Eugene Mikhantyev
3e84957698 style: apply Black formatting to pin_locator.py
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 12:38:17 +01:00
Eugene Mikhantyev
8b0ed30ee3 style: revert Prettier formatting in TS files
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 12:30:16 +01:00
Eugene Mikhantyev
7d53272cb1 fix: replace hardcoded contributor paths in __main__ blocks
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>
2026-03-29 12:28:27 +01:00
Eugene Mikhantyev
038beb6d26 refactor: use module-level Symbol constants in delete_wire and delete_label
Replace inline Symbol() allocations with the existing _SYM_WIRE/_SYM_PTS/_SYM_XY
constants and new _SYM_AT/_SYM_LABEL constants for consistency.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 12:22:54 +01:00
Eugene Mikhantyev
a11dd5fac9 style: apply Black and Prettier formatting to PR-changed files
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 12:22:54 +01:00
mixelpixx
a76c5bc74b Merge pull request #61 from Mehanik/fix/tool-schema-descriptions
feat: add_schematic_wire & add_schematic_junction with pin snapping and polyline routing
2026-03-28 15:40:58 -04:00
mixelpixx
ac1ea89eb5 Merge pull request #74 from mfiumara/feature/move-component-layer-option
Add layer option to move_component tool
2026-03-27 20:31:13 -04:00
mixelpixx
26e08b94bc Merge pull request #77 from gevangelopoulos/feat/kicad-mod-parser
feat: reusable kicad mod parser
2026-03-27 19:49:12 -04:00
George Evangelopoulos
7ab88adaed kicad_mod parser 2026-03-27 20:22:17 +01:00
George Evangelopoulos
b467d1cff9 fixed broken tool due to naming inconsistencies 2026-03-27 19:52:54 +01:00
Mattia Fiumara
dd388470be Add layer option to move_component to support flipping components
Adds an optional `layer` parameter (e.g., 'F.Cu', 'B.Cu') to the
move_component tool. When specified, the component is flipped to
the target layer if it's not already on it. The response now also
includes the component's layer after the move.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-25 18:09:24 +01:00
mixelpixx
c48fa64e0f Update fmt.Println output from 'Hello' to 'Goodbye' 2026-03-24 21:04:17 -04:00
mixelpixx
b02c3ba6fe Merge pull request #71 from LeahArmstrong/fix/jlcpcb-download-and-search
fix: JLCPCB database download and FTS search

Thanks! you rock.  JLCPCB parts things has been a headache. I will look over the whole implementation this weekend.
2026-03-24 20:53:27 -04:00
mixelpixx
647a131b8a Merge pull request #62 from Mehanik/feature/wire-connectivity-lookup
feat: add get_wire_connections — schematic net traversal from a point
2026-03-24 19:06:07 -04:00
Eugene Mikhantyev
3bd3c3a962 feat: add wire/junction tools with pin-snapping and T-junction support
- Rename add_schematic_connection → add_schematic_wire with waypoints[] parameter
- Add snapToPins (default true) to snap wire endpoints to nearest pin
- Expose add_schematic_junction as an MCP tool
- Break existing wires at new wire endpoints for T-junction support
- Remove orphaned add_connection / add_wire / get_pin_location from ConnectionManager
- Update tool registry to reflect renamed schematic tools in TS layer
- Add 76 tests for wire/junction handler dispatch, schema validation, and WireManager corner cases
- Apply Black and Prettier formatting to changed files

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 21:46:36 +00:00
Eugene Mikhantyev
9f89437918 chore: apply Black formatting and add tests for get_wire_connections
- Apply Black formatting to wire_connectivity.py, kicad_interface.py,
  and tool_schemas.py (changed files only)
- Add python/tests/conftest.py with pcbnew/skip C-extension stubs
- Add python/tests/test_wire_connectivity.py with 29 unit tests covering
  schema validation, handler dispatch, parameter validation, and core
  logic (_to_iu, _parse_wires, _build_adjacency, _find_connected_wires,
  get_wire_connections)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 19:26:25 +00:00
Eugene Mikhantyev
018f4a278d refactor: switch get_wire_connections to exact IU matching throughout
Remove the 0.5mm query tolerance in favour of exact integer-unit matching
on all coordinate lookups (seed, label bridging, pin matching), mirroring
KiCad's own connectivity algorithm. Callers must supply exact wire endpoint
coordinates (e.g. from list_schematic_wires).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 19:24:38 +00:00
Eugene Mikhantyev
8414784b78 docs: clarify get_wire_connections requires endpoint coordinates
Update tool description and Python docstring to make clear that the
query point must be at a wire endpoint or junction — midpoints of
wire segments are not matched.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 19:24:38 +00:00
Eugene Mikhantyev
de0eca2ed7 refactor: remove redundant junction processing from wire connectivity
Shared-endpoint adjacency already connects all wires meeting at the same
point, making explicit junction handling a no-op duplicate.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 19:24:38 +00:00
Eugene Mikhantyev
f120034846 refactor: extract wire connectivity into module with KiCad-native IU matching
Move wire connectivity logic from _handle_get_wire_connections into
commands/wire_connectivity.py. Use KiCad's internal integer unit system
(10,000 IU/mm) with exact coordinate matching instead of tolerance-based
float comparison, mirroring how KiCad itself determines connectivity.

Key improvements:
- Exact integer matching for wire endpoints (O(1) dict lookup vs O(n) grid scan)
- Junction support for T-connections
- Multi-unit symbol support (removed incorrect processed_refs dedup)
- Single public API: get_wire_connections()

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 19:24:38 +00:00
Eugene Mikhantyev
4277a3d000 refactor: use pre-compiled adjacency list for BFS in get_wire_connections
Replace runtime spatial-index queries during BFS with a pre-compiled
adjacency list for O(1) edge traversal. Also fix potential UnboundLocalError
for `ref` in the pin-checking exception handler and simplify validation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-24 19:24:38 +00:00
Eugene Mikhantyev
b257bef89b fix: harden get_wire_connections against edge cases and improve performance
- Add +1 safety margin to grid_radius to handle banker's rounding at cell
  boundaries in the spatial index
- Move symbol property guards inside per-symbol try/except to prevent
  AttributeError from aborting all pin processing
- Replace O(n) connected_points scan for pin matching with spatial index
  lookup (_frontier_has_neighbour), consistent with flood-fill approach
- Wrap float(x)/float(y) conversion with clear user-facing error message

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 19:24:38 +00:00
Eugene Mikhantyev
ddbfc62a49 fix: address review issues in get_wire_connections
- Fix critical bug: use pin_data[0]/[1] instead of pin_data["x"]/["y"]
  (get_all_symbol_pins returns List[float], not dict)
- Use index-based wire tracking to avoid fragile float list equality
- Check all polyline points (not just endpoints) during flood-fill
- Add spatial index (0.05mm grid) to replace O(n²) frontier scan
- Skip already-processed refs to avoid redundant calls for multi-unit symbols
- Include wires_out in early return when schematic has no symbols
- Add get_wire_connections schema entry to tool_schemas.py

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-24 19:24:38 +00:00