Skip to content

KiCad (component library repo)

Repo: ~/Documents/GitHub/KiCad — symbols/, footprints/, 3dmodels/, blocks/, template/.

Facts

  • Field conventions: kicad-symbol-fields
  • ~8,660 symbols; ~8,300 carry an MPN but under 5 field names: "Manufacturer Part Number" (8339), "Manufacturer_Part_Number" (95), "Manufacturer Product Number" (77, +8 with trailing space), "Part Number" (12), "Part_Number" (11). ~8,190 carry a "JLCPCB" LCSC number.
  • Bulk is Yageo passives (5,557), Panasonic (622), onsemi (538), Bourns (457).

Open

See ~/Notes/tasks.md — this section is now generated from the task register.

Log

  • 2026-09-09 Researched KiCost for lifecycle/cost. KiCost v1.1.20 (Mar 2025) is BOM-oriented, leans on Octopart (now paid) plus scrapers; it does flag obsolete/NRND but is the wrong shape for a library scan. Plan: use official digikey-apiv4 (ProductStatus, datasheet, pricing) + mouser PyPI for dual-source, key on the MPN field; normalise the 5 MPN field names first. For symbol generation: easyeda2kicad (LCSC) / kandle (SnapEDA, Ultra Librarian ZIPs); no free tool generates symbols straight from the Digi-Key API. Parser: kiutils is stale; a symbol-only s-expression pass is enough.
  • 2026-09-09 Wrote scripting/normalize_mpn.py (unified 5 MPN field names → "Manufacturer Part Number", 204 renames, 1 dup dropped; preserves CRLF) and scripting/lifecycle_scan.py (Mouser part-number search, stdlib only, full raw JSON cached in scripting/.cache/mouser.json, 30-day refresh, CSV report). 6,814 unique MPNs → ~7 days at Mouser's 1,000/day quota. Key lives in ~/.config/kicad-libsync.env.
  • 2026-09-09 Decision: sourcing fields on every symbol are exactly Description, Manufacturer, Manufacturer Part Number, Datasheet, LCSC (not JLCPCB; LCSC is what kicad-jlcpcb-tools/easyeda2kicad read by default). scripting/standardize_fields.py enforces it: renamed JLCPCB/JLCPCB Part #/Part#/Alt, stripped whitespace, dropped stray Field6/KLC_*/PARTREV, added empty hidden placeholders. All 8,661 symbols now pass; kicad-cli parses all 26 libs. Three odd-indent single-symbol libs were reformatted with kicad-cli sym upgrade --force. Run order: normalize_mpn.py then standardize_fields.py. Uncommitted in working tree.
  • 2026-09-09 Digi-Key Product Information v4 wired into scripting/lifecycle_scan.py (client-credentials OAuth, no callback; token lives 10 min). --source mouser|digikey, caches in scripting/.cache/<source>.json. Digi-Key Description.ProductDescription is the uppercase catalogue style for kicad-symbol-fields; DetailedDescription is the long one. Both quotas 1,000/day; run each daily with --limit 950.
  • 2026-09-09 Built part-lookup CLI: source scripting/partlookup.py, shim ~/.local/bin/part-lookup, subcommands get / search / lib. Permanent per-part raw cache at ~/.local/share/part-cache/<source>/, shared with lifecycle_scan.py (old .cache/*.json migrated, 1,905 entries). Global skill ~/.claude/skills/part-lookup/SKILL.md + pointer in ~/.claude/CLAUDE.md so every project uses it instead of browsing. Gotchas: Mouser returns prices as "$0.10" strings and stock as strings; Digi-Key QuantityAvailable can be null with stock only in ProductVariations. Digi-Key keyword search returns reel-variant MPNs (RC0402FR-13…), so lib must be checked by value, not by the search result MPN.

Checks — kicad-cli, KiCad 10 (2026-09-13)

kicad-cli is installed as a wrapper around the pinned kicad/kicad:10.0.5 container (~/.local/bin/kicad-cli) — no sudo apt, and a pinned version means a check that passes here passes the same way in CI. kicad-check runs ERC and DRC over every schematic and board in a repo and prints, or emits JSON for the audit.

Three things it had to learn before its numbers meant anything:

  1. It generates the library tables itself. There is no fp-lib-table or sym-lib-table in the repo, so a fresh clone cannot resolve our libraries and reports thirty "footprint library not configured" warnings. Generated from the repo's own .pretty and .kicad_sym files, the same everywhere.
  2. A block is a fragment, not a design. Unconnected pins and undriven power rails are the point of a reusable block — the parent design provides them. Counting them gave 227 "errors" across 44 projects, nearly all meaningless. Anything under blocks/ or template/ is exempt from that class.
  3. A dangling label in a fragment is downgraded, not exempt. It is often the interface to the parent, and it is also exactly how a typo looks — so it is a warning for a person to judge once, not a guess by the tool.

Version matters more than it looks. The first run used KiCad 9 and reported 21 errors; 10.0.5 reports 57 across 22 projects. The repo is mixed — block schematics are still the v9 format (20250114) while the symbol library is already v10 (20251024) — so the older CLI was reading a newer library. Design happens in 10, so 10 is what the checks use.

The real findings are mostly manufacturing: usb_c and USB_C carry 16 DRC errors each (clearance, one at 0.1984 mm against a 0.2 mm rule; hole clearance; an invalid outline).

Next: wire kicad-check --json into sop-audit as a SOP-008 check so the count lands on the board and stays visible, and see engineering-portal for the pages built on top.

kicad-ibom — the BOM you use at the bench (2026-09-14)

kicad-ibom board.kicad_pcb writes a single self-contained HTML file: click a BOM line and the part highlights on the board, front and back. It is a production tool, not a drawing — it is what belongs on a tablet while populating a board.

  • InteractiveHtmlBom 2.12, vendored at ~/.local/share/ibom, run inside the pinned KiCad container because it needs pcbnew.
  • Headless works via INTERACTIVE_HTML_BOM_NO_DISPLAY=1; without it the tool wants an X server and the container has none (there is no xvfb in the image either).
  • Verified self-contained: no external CSS, JS or fonts, so it opens from a USB stick or an offline tablet. 325 kB for the JLCPCB template board.

It refuses a board with nothing on Edge.Cuts, and that refusal is correct rather than a bug: blocks/usb_c and several other blocks have no outline, which is the same thing DRC reports as invalid_outline. A block that is only ever dropped into a parent board may not need one — but then it does not get an interactive BOM either, and that is the honest answer.

Next: generate one per board in CI and publish it, which is what engineering-portal shows.