diff --git a/README.md b/README.md new file mode 100644 index 0000000..60e5951 --- /dev/null +++ b/README.md @@ -0,0 +1,192 @@ +# claude-kicad-helper + +A command-line query tool for KiCad project files, designed to extract +focused, readable information from files that are otherwise too large to +work with directly. + +## Why this exists + +KiCad stores schematics (`.kicad_sch`) and PCB layouts (`.kicad_pcb`) as +S-expression trees that easily run to thousands of lines. Most of that bulk +is graphical metadata — line coordinates, font sizes, courtyard polygons — +that is irrelevant when you want to answer questions like: + +- What components are on this board and what are their values? +- Which nets exist in this schematic? +- What copper traces physically connect to pin 1 of R5? + +`kicad-query.mjs` parses the file, extracts structured data, and prints +only what was asked for — either as a human-readable table or as JSON for +programmatic/LLM consumption. + +## Architecture + +``` +tokenize(text) generic S-expression tokenizer +parse_sexp(text) builds { tag, items[] } tree + │ + ▼ +run_query(ext, query, root, args) file-type + query dispatch → plain data object + │ + ├── render_human(ext, query, data) formatted tables for terminal + └── render_json(data) JSON.stringify for LLM / scripts +``` + +Query functions are pure data transformers — no I/O, no format awareness. +Adding a new output format only requires a new renderer. + +## Requirements + +Node.js 18+ (uses ES modules, no dependencies). + +## Usage + +``` +node kicad-query.mjs [--format=json] [args...] +``` + +## Queries + +### Schematic (`.kicad_sch`) + +| Query | Description | +|-------|-------------| +| `summary` | Component counts, wire count, libraries used | +| `components` | Table of all placed components (ref, value, footprint) | +| `components ref=U*` | Filter by reference glob | +| `components value=100nF` | Filter by value glob | +| `component U1` | All properties and pins of one component | +| `nets` | All net names (local labels, global labels, power nets) | + +### PCB (`.kicad_pcb`) + +| Query | Description | +|-------|-------------| +| `summary` | Net, footprint, segment, via, zone counts | +| `nets` | All nets with their numeric IDs | +| `net GND` | Which pads are connected to a named net | +| `footprints` | Table of all footprints | +| `footprint R5` | Position, layer, value, pad→net table for one footprint | +| `traces R5 1` | BFS through segments and vias from pad 1 of R5 | + +### Project (`.kicad_pro`) + +| Query | Description | +|-------|-------------| +| `summary` | Filename, version, min clearance, section list | + +### Generic (any file) + +| Query | Description | +|-------|-------------| +| `tags` | All S-expression tag names sorted by frequency — useful for exploration | +| `raw ` | Dump all nodes with a given tag name | + +--- + +## Examples — human output + +``` +$ node kicad-query.mjs sketch.kicad_sch summary +=== Schematic Summary === +Components : 26 +Power symbols: 14 +Net labels : 0 +Global labels: 16 +Wires : 102 + +Libraries: + Amplifier_Operational: 1 + Connector: 4 + Device: 16 + Mechanical: 4 +``` + +``` +$ node kicad-query.mjs sketch.kicad_sch components +Reference Value Library:Symbol Footprint +--------- ----- -------------- --------- +C1 100 nF Device:C Capacitor_SMD:C_0603_1608Metric +C5 100 µF Device:C_Polarized Capacitor_SMD:CP_Elec_6.3x4.5 +R4 100 mΩ Device:R Resistor_SMD:R_1206_3216Metric +U1 LM358 Amplifier_Operational:LM358 Package_SO:SO-8_3.9x4.9mm_P1.27mm +... +``` + +``` +$ node kicad-query.mjs sketch.kicad_sch nets +=== Net Names (10 total) === + BIAS [global] + Current Measurement [global] + GND [power] + SUPPLY [global] + VDD [power] + Voltage Reference [global] + ... +``` + +``` +$ node kicad-query.mjs sketch.kicad_pcb traces R5 1 +=== Traces from R5 pad 1 === +Net : Current Reference (id=12) +Position : (148.645, 64.350) +Pad layers : F.Cu + +Layer B.Cu — 2 segment(s): + From (x, y) To (x, y) Width + (153.162, 74.168) → (153.670, 73.660) 0.4mm + (153.162, 81.026) → (153.162, 74.168) 0.4mm + +Layer F.Cu — 9 segment(s): + ... + +Vias (2): + (153.670, 73.660) F.Cu ↔ B.Cu + (153.162, 81.026) F.Cu ↔ B.Cu +``` + +--- + +## Examples — JSON / LLM output + +Add `--format=json` before the filename. All queries produce the same data; +only the presentation changes. + +``` +$ node kicad-query.mjs --format=json sketch.kicad_sch components +{ + "components": [ + { + "ref": "C1", + "value": "100 nF", + "footprint": "Capacitor_SMD:C_0603_1608Metric", + "lib_id": "Device:C", + "datasheet": "~", + "dnp": false + }, + ... + ] +} +``` + +``` +$ node kicad-query.mjs --format=json sketch.kicad_pcb traces R5 1 +{ + "ref": "R5", + "pad": "1", + "net": { "id": 12, "name": "Current Reference" }, + "position": { "x": 148.645, "y": 64.35 }, + "pad_layers": ["F.Cu"], + "traces": [ + { "layer": "F.Cu", "start": { "x": 149.225, "y": 64.35 }, "end": { "x": 148.645, "y": 64.35 }, "width": 0.4 }, + ... + ], + "vias": [ + { "position": { "x": 153.670, "y": 73.660 }, "layers": ["F.Cu", "B.Cu"] } + ] +} +``` + +When feeding KiCad data to an LLM, prefer `--format=json` with targeted +queries over pasting raw file contents. A 6000-line schematic collapses to +a few hundred bytes of component and net data.