Ports the write path of io/specctra/SesWriter.java to emit a valid session from a parsed DsnBoard plus a RoutingResult. Each _write_* function mirrors a write* method upstream: - session scope with base_design, placement (resolution + components echoed from the DSN), an empty was_is, and routes - routes carries resolution, a reduced parser scope, library_out with the via padstacks, and network_out - network_out emits (net (wire (path layer width x1 y1 ...)) (via padstack x y)) for each routed net; integer coordinates via round- half-up to match Java Math.round write_ses(board) with no result produces a valid no-op session, proving the DSN-in / SES-out round trip. Only routes > network_out is required by SesReader and kicad-cli; the rest is echoed for a well-formed file. 18 tests: indent/quoting rules, no-op session structure, placement and library_out echo, routed wire/via serialization, integer rounding, and round-trips re-parsed through the project's own DSN tokenizer/sexp (64 tests total across the suite, all green; ruff clean).
freeroute
A native Python PCB autorouter — a Java-free port of the FreeRouting engine.
Why
kicad-mcp currently autoroutes by shelling out to freerouting.jar, which
drags in a JVM dependency. freeroute reimplements the routing engine in
pure Python so the toolchain needs no Java at all.
The contract
The entire integration surface is two Specctra files:
board.dsn ──▶ freeroute ──▶ board.ses
(unrouted) (routed session: traces + vias)
kicad-cli already exports .dsn and imports .ses, so freeroute is a
drop-in replacement for the JAR step — nothing else in the pipeline changes.
Status
Pre-alpha. Under active development. See docs/PORTING_PLAN.md
for the architecture and porting roadmap.
Usage (target)
freeroute board.dsn -o board.ses
Development
uv sync
uv run pytest
uv run ruff check src/ tests/
License
GPL-3.0-or-later, matching the FreeRouting source it is ported from.
Languages
Python
100%