kicad_skills

Working in this repository

eda is a command-line toolkit for circuit design — datasheets, SPICE simulation, KiCad schematic and board review, fabrication output — implemented as the eda_toolkit Python package and executed inside a container.

This file is the working agreement for anyone changing the code: humans, and coding agents alike. (CLAUDE.md points here; there is one copy, not two.)

Ground rules

Development

make build        # build (or rebuild) the image
make test         # full suite in the container - this is the gate
make test-host    # fast pure-python subset (needs .venv with the test extra)
make smoke        # end-to-end run of every top-level command

make test mounts the working tree and puts /work/src on PYTHONPATH, so it tests the code you are editing, not the copy baked into the image. Rebuild the image only when the Dockerfile or the dependencies change.

CI runs the suite against every KiCad version in the ci.yml matrix (currently 10.0.4 and 9.0.9). Run make test KICAD_VERSION=9.0.9 before pushing anything that touches kicad_cli.py, the fixtures or the review rules. Not every flag exists in every release: gate on kicad_cli.supports([...], "--flag") rather than on a version number, and keep the fixtures in the oldest format the matrix covers — KiCad never reads a file newer than itself.

Adding a review rule

Rules are functions registered with the @rule decorator in src/eda_toolkit/kicad/sch_review.py or pcb_review.py. They receive a context (parsed design + netlist/board + ERC/DRC output) and return Finding objects. Add the rule, then add a test in tests/test_sch_review.py / tests/test_pcb_review.py using the in-memory ReviewContext.from_netlist / PcbContext.from_board constructors — no filesystem needed.

Keep severities honest: error = the design is broken, warning = a human must judge it, info = context.

Tuning a rule

tools/review_demos.py runs both reviews over the 18 KiCad demo projects in the image and aggregates the findings per rule. Use it before and after changing a rule: a rule that fires thousands of times across that corpus is noise, however correct each instance is. Findings that repeat more than COLLAPSE_LIMIT times are folded into one entry by util.collapse_findings, so prefer grading a rule (warning vs info) over deleting it.

Pinning rules (enforced by tests/test_pinning.py)

Test fixtures

tests/fixtures/example_project is a small, DRC-clean KiCad project (RC filter

Documentation

When behaviour changes, update the guide that covers it in the same commit. A guide that describes a flag the CLI no longer has is worse than no guide.

These same files are the website: GitHub Pages serves main / (root) with the settings in _config.yml — no build workflow, no gh-pages branch, nothing generated. That puts three constraints on anything published (README.md, AGENTS.md, docs/**), all enforced by tests/test_docs.py:

make site renders it locally with the same pinned gem set Pages uses, which is how those three were found in the first place.

bin/install-skills.sh renders docs/guides/ into Claude Code’s skill layout (.claude/skills/<name>/SKILL.md, symlinks, git-ignored). Never edit that copy: it is generated, and make skills regenerates it.