boardforge 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (301) hide show
  1. boardforge-0.1.0/LICENSE +21 -0
  2. boardforge-0.1.0/PKG-INFO +258 -0
  3. boardforge-0.1.0/README.md +229 -0
  4. boardforge-0.1.0/pyproject.toml +60 -0
  5. boardforge-0.1.0/setup.cfg +4 -0
  6. boardforge-0.1.0/src/boardforge/__init__.py +7 -0
  7. boardforge-0.1.0/src/boardforge/analysis/__init__.py +259 -0
  8. boardforge-0.1.0/src/boardforge/cli.py +280 -0
  9. boardforge-0.1.0/src/boardforge/config.py +218 -0
  10. boardforge-0.1.0/src/boardforge/datasheets.py +604 -0
  11. boardforge-0.1.0/src/boardforge/drc.py +71 -0
  12. boardforge-0.1.0/src/boardforge/fabs/__init__.py +18 -0
  13. boardforge-0.1.0/src/boardforge/fabs/base.py +108 -0
  14. boardforge-0.1.0/src/boardforge/fabs/jlcpcb/__init__.py +60 -0
  15. boardforge-0.1.0/src/boardforge/fabs/jlcpcb/profile.toml +56 -0
  16. boardforge-0.1.0/src/boardforge/kicad.py +189 -0
  17. boardforge-0.1.0/src/boardforge/netlist.py +118 -0
  18. boardforge-0.1.0/src/boardforge/pcb/__init__.py +8 -0
  19. boardforge-0.1.0/src/boardforge/pcb/astar.py +543 -0
  20. boardforge-0.1.0/src/boardforge/pcb/build.py +158 -0
  21. boardforge-0.1.0/src/boardforge/pcb/common.py +112 -0
  22. boardforge-0.1.0/src/boardforge/pcb/congestion.py +116 -0
  23. boardforge-0.1.0/src/boardforge/pcb/fanout.py +278 -0
  24. boardforge-0.1.0/src/boardforge/pcb/fiducials.py +104 -0
  25. boardforge-0.1.0/src/boardforge/pcb/finish.py +215 -0
  26. boardforge-0.1.0/src/boardforge/pcb/measure.py +76 -0
  27. boardforge-0.1.0/src/boardforge/pcb/pinswap.py +143 -0
  28. boardforge-0.1.0/src/boardforge/pcb/place.py +556 -0
  29. boardforge-0.1.0/src/boardforge/pcb/specctra.py +24 -0
  30. boardforge-0.1.0/src/boardforge/pcbfile.py +41 -0
  31. boardforge-0.1.0/src/boardforge/physical.py +811 -0
  32. boardforge-0.1.0/src/boardforge/project.py +116 -0
  33. boardforge-0.1.0/src/boardforge/render.py +66 -0
  34. boardforge-0.1.0/src/boardforge/review/__init__.py +0 -0
  35. boardforge-0.1.0/src/boardforge/review/bom_check.py +280 -0
  36. boardforge-0.1.0/src/boardforge/review/budget.py +92 -0
  37. boardforge-0.1.0/src/boardforge/review/constraints.py +61 -0
  38. boardforge-0.1.0/src/boardforge/review/datasheet_check.py +172 -0
  39. boardforge-0.1.0/src/boardforge/review/gate.py +80 -0
  40. boardforge-0.1.0/src/boardforge/review/package_check.py +246 -0
  41. boardforge-0.1.0/src/boardforge/review/spice_path.py +351 -0
  42. boardforge-0.1.0/src/boardforge/routers/__init__.py +17 -0
  43. boardforge-0.1.0/src/boardforge/routers/astar.py +87 -0
  44. boardforge-0.1.0/src/boardforge/routers/base.py +77 -0
  45. boardforge-0.1.0/src/boardforge/routers/freerouting.py +58 -0
  46. boardforge-0.1.0/src/boardforge/routers/specctra.py +84 -0
  47. boardforge-0.1.0/src/boardforge/skidl_runner.py +144 -0
  48. boardforge-0.1.0/src/boardforge/state.py +54 -0
  49. boardforge-0.1.0/src/boardforge/units.py +33 -0
  50. boardforge-0.1.0/src/boardforge/vendor/README.md +5 -0
  51. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/LICENSE +21 -0
  52. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/VENDORED.md +25 -0
  53. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/how-it-works.md +254 -0
  54. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/bom/SKILL.md +378 -0
  55. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/bom/references/kicad-fields.md +68 -0
  56. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/bom/references/ordering-and-fabrication.md +150 -0
  57. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/bom/references/part-number-conventions.md +409 -0
  58. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/bom/scripts/bom_manager.py +1298 -0
  59. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/bom/scripts/edit_properties.py +438 -0
  60. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/bom/scripts/kicad_sexp.py +85 -0
  61. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/bom/scripts/sync_datasheet_urls.py +393 -0
  62. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/bom/scripts/translate_bom_pnp.py +731 -0
  63. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/SKILL.md +119 -0
  64. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/datasheet_types/__init__.py +80 -0
  65. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/datasheet_types/__pycache__/__init__.cpython-314.pyc +0 -0
  66. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/datasheet_types/__pycache__/base_block.cpython-314.pyc +0 -0
  67. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/datasheet_types/__pycache__/codec.cpython-314.pyc +0 -0
  68. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/datasheet_types/__pycache__/extraction.cpython-314.pyc +0 -0
  69. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/datasheet_types/__pycache__/pinout.cpython-314.pyc +0 -0
  70. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/datasheet_types/__pycache__/regulator.cpython-314.pyc +0 -0
  71. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/datasheet_types/__pycache__/spec_value.cpython-314.pyc +0 -0
  72. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/datasheet_types/__pycache__/trust_gating.cpython-314.pyc +0 -0
  73. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/datasheet_types/base_block.py +132 -0
  74. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/datasheet_types/codec.py +174 -0
  75. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/datasheet_types/extraction.py +177 -0
  76. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/datasheet_types/pinout.py +117 -0
  77. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/datasheet_types/regulator.py +95 -0
  78. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/datasheet_types/spec_value.py +51 -0
  79. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/datasheet_types/trust_gating.py +125 -0
  80. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/examples/abm8g-106-12.000mhz-t.json +372 -0
  81. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/examples/irlml6344.json +616 -0
  82. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/examples/lm2596-adj.json +507 -0
  83. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/examples/lm358.json +598 -0
  84. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/examples/mbrs540t3g.json +498 -0
  85. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/examples/stm32f103c8t6.json +2090 -0
  86. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/prompts/base.md +56 -0
  87. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/prompts/crystal.md +127 -0
  88. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/prompts/diode.md +89 -0
  89. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/prompts/mcu.md +163 -0
  90. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/prompts/opamp.md +164 -0
  91. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/prompts/pinout.md +54 -0
  92. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/prompts/regulator.md +56 -0
  93. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/prompts/scout.md +68 -0
  94. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/prompts/transistor.md +145 -0
  95. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/references/cache-layout.md +183 -0
  96. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/references/consumer-api.md +240 -0
  97. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/references/dispatch-claude-code.md +179 -0
  98. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/references/dispatcher-contract.md +112 -0
  99. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/references/extraction-pipeline.md +24 -0
  100. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/references/extraction-schema.md +387 -0
  101. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/references/field-extraction-guide.md +262 -0
  102. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/references/quality-scoring.md +205 -0
  103. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/schemas/CHANGELOG.md +180 -0
  104. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/schemas/base.schema.json +181 -0
  105. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/schemas/crystal.schema.json +106 -0
  106. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/schemas/diode.schema.json +148 -0
  107. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/schemas/extraction.schema.json +91 -0
  108. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/schemas/fixtures/lm2596-adj.example.json +507 -0
  109. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/schemas/fixtures/manifest.example.json +31 -0
  110. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/schemas/fixtures/minimal.example.json +95 -0
  111. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/schemas/manifest.schema.json +69 -0
  112. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/schemas/mcu.schema.json +252 -0
  113. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/schemas/opamp.schema.json +167 -0
  114. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/schemas/pinout.schema.json +130 -0
  115. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/schemas/plan.schema.json +100 -0
  116. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/schemas/regulator.schema.json +156 -0
  117. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/schemas/scout.schema.json +68 -0
  118. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/schemas/spec_value.schema.json +62 -0
  119. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/schemas/transistor.schema.json +221 -0
  120. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/scripts/__pycache__/datasheet_extract_cache.cpython-314.pyc +0 -0
  121. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/scripts/__pycache__/datasheet_features.cpython-314.pyc +0 -0
  122. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/scripts/__pycache__/datasheet_lookup.cpython-314.pyc +0 -0
  123. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/scripts/__pycache__/datasheet_score.cpython-314.pyc +0 -0
  124. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/scripts/__pycache__/datasheet_verify.cpython-314.pyc +0 -0
  125. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/scripts/_smoke_v14_roundtrip.py +211 -0
  126. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/scripts/datasheet_extract_cache.py +541 -0
  127. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/scripts/datasheet_features.py +423 -0
  128. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/scripts/datasheet_lookup.py +243 -0
  129. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/scripts/datasheet_page_selector.py +500 -0
  130. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/scripts/datasheet_score.py +459 -0
  131. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/scripts/datasheet_verify.py +1070 -0
  132. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/scripts/merge_results.py +318 -0
  133. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/scripts/plan_extraction.py +198 -0
  134. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/scripts/validate_extraction_result.py +142 -0
  135. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/datasheets/scripts/validate_sanity_vector.py +157 -0
  136. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/digikey/SKILL.md +377 -0
  137. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/digikey/scripts/fetch_datasheet_digikey.py +547 -0
  138. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/digikey/scripts/sync_datasheets_digikey.py +908 -0
  139. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/element14/SKILL.md +273 -0
  140. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/element14/scripts/fetch_datasheet_element14.py +516 -0
  141. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/element14/scripts/sync_datasheets_element14.py +775 -0
  142. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/emc/SKILL.md +206 -0
  143. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/emc/references/emc-methodology.md +142 -0
  144. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/emc/references/emc-standards.md +110 -0
  145. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/emc/references/pcb-emc-rules.md +381 -0
  146. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/emc/scripts/__pycache__/emc_envelope.cpython-314.pyc +0 -0
  147. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/emc/scripts/__pycache__/emc_formulas.cpython-314.pyc +0 -0
  148. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/emc/scripts/__pycache__/emc_rules.cpython-314.pyc +0 -0
  149. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/emc/scripts/analyze_emc.py +682 -0
  150. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/emc/scripts/emc_envelope.py +291 -0
  151. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/emc/scripts/emc_formulas.py +1392 -0
  152. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/emc/scripts/emc_rules.py +4552 -0
  153. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/emc/scripts/emc_spice.py +708 -0
  154. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/jlcpcb/SKILL.md +233 -0
  155. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/SKILL.md +850 -0
  156. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/references/config-reference.md +356 -0
  157. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/references/datasheet-verification.md +322 -0
  158. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/references/deep-review.md +162 -0
  159. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/references/design-intent.md +123 -0
  160. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/references/diff-analysis.md +355 -0
  161. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/references/file-formats.md +379 -0
  162. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/references/gerber-parsing.md +729 -0
  163. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/references/manual-gerber-parsing.md +621 -0
  164. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/references/manual-pcb-parsing.md +467 -0
  165. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/references/manual-schematic-parsing.md +289 -0
  166. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/references/net-tracing.md +169 -0
  167. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/references/oshwa-certification.md +89 -0
  168. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/references/output-schema.md +317 -0
  169. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/references/pcb-layout-analysis.md +447 -0
  170. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/references/pdf-schematic-extraction.md +315 -0
  171. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/references/report-generation.md +696 -0
  172. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/references/schematic-analysis.md +1165 -0
  173. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/references/standards-compliance.md +638 -0
  174. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/references/supplementary-data-sources.md +288 -0
  175. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/references/what-if.md +500 -0
  176. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/review/README.md +46 -0
  177. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/review/fixtures/deep_review.example.json +39 -0
  178. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/review/fixtures/design_context.example.json +9 -0
  179. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/review/fixtures/review_annotations.example.json +22 -0
  180. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/review/prompts/design_context.md +100 -0
  181. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/review/schemas/deep_review.schema.json +72 -0
  182. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/review/schemas/design_context.schema.json +59 -0
  183. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/review/schemas/review_annotations.schema.json +49 -0
  184. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/review/scripts/_mini_jsonschema.py +173 -0
  185. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/review/scripts/build_review_plan.py +65 -0
  186. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/review/scripts/deep_review_gate.py +347 -0
  187. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/review/scripts/merge_annotations.py +175 -0
  188. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/review/scripts/run_phase4_exercise.py +281 -0
  189. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/review/scripts/validate_review.py +72 -0
  190. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/README.md +389 -0
  191. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/__pycache__/analyzer_envelope.cpython-314.pyc +0 -0
  192. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/__pycache__/bus_resolver.cpython-314.pyc +0 -0
  193. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/__pycache__/capability_mode.cpython-314.pyc +0 -0
  194. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/__pycache__/detection_schema.cpython-314.pyc +0 -0
  195. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/__pycache__/detector_helpers.cpython-314.pyc +0 -0
  196. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/__pycache__/domain_detectors.cpython-314.pyc +0 -0
  197. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/__pycache__/finding_schema.cpython-314.pyc +0 -0
  198. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/__pycache__/inputs_builder.cpython-314.pyc +0 -0
  199. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/__pycache__/kicad_types.cpython-314.pyc +0 -0
  200. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/__pycache__/kicad_utils.cpython-314.pyc +0 -0
  201. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/__pycache__/lookup_detectors.cpython-314.pyc +0 -0
  202. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/__pycache__/lookup_helpers.cpython-314.pyc +0 -0
  203. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/__pycache__/netlist_queries.cpython-314.pyc +0 -0
  204. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/__pycache__/output_filters.cpython-314.pyc +0 -0
  205. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/__pycache__/pcb_connectivity.cpython-314.pyc +0 -0
  206. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/__pycache__/project_config.cpython-314.pyc +0 -0
  207. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/__pycache__/run_id.cpython-314.pyc +0 -0
  208. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/__pycache__/schema_codec.cpython-314.pyc +0 -0
  209. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/__pycache__/sexp_parser.cpython-314.pyc +0 -0
  210. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/__pycache__/signal_detectors.cpython-314.pyc +0 -0
  211. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/__pycache__/validation_detectors.cpython-314.pyc +0 -0
  212. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/analysis_cache.py +604 -0
  213. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/analyze_gerbers.py +1670 -0
  214. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/analyze_pcb.py +7544 -0
  215. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/analyze_schematic.py +10421 -0
  216. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/analyze_thermal.py +1222 -0
  217. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/analyzer_envelope.py +295 -0
  218. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/bus_resolver.py +289 -0
  219. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/capability_mode.py +218 -0
  220. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/check_report_sections.py +201 -0
  221. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/cross_analysis.py +1201 -0
  222. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/cross_verify.py +657 -0
  223. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/detection_schema.py +654 -0
  224. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/detector_helpers.py +76 -0
  225. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/diff_analysis.py +1596 -0
  226. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/domain_detectors.py +6161 -0
  227. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/envelopes/__init__.py +0 -0
  228. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/envelopes/__pycache__/__init__.cpython-314.pyc +0 -0
  229. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/envelopes/__pycache__/gerber.cpython-314.pyc +0 -0
  230. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/envelopes/__pycache__/pcb.cpython-314.pyc +0 -0
  231. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/envelopes/__pycache__/schematic.cpython-314.pyc +0 -0
  232. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/envelopes/__pycache__/thermal.cpython-314.pyc +0 -0
  233. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/envelopes/cross_analysis.py +132 -0
  234. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/envelopes/gerber.py +355 -0
  235. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/envelopes/pcb.py +395 -0
  236. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/envelopes/schematic.py +450 -0
  237. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/envelopes/thermal.py +144 -0
  238. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/export_issues.py +547 -0
  239. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/fab_release_gate.py +604 -0
  240. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/finding_schema.py +715 -0
  241. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/gen_output_schema_md.py +230 -0
  242. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/inputs_builder.py +107 -0
  243. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/kicad_types.py +117 -0
  244. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/kicad_utils.py +2278 -0
  245. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/lifecycle_audit.py +1137 -0
  246. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/lookup_detectors.py +701 -0
  247. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/lookup_helpers.py +60 -0
  248. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/methodology_gerbers.md +447 -0
  249. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/methodology_pcb.md +473 -0
  250. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/methodology_schematic.md +892 -0
  251. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/netlist_queries.py +360 -0
  252. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/output_filters.py +468 -0
  253. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/pcb_connectivity.py +516 -0
  254. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/project_config.py +956 -0
  255. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/run_id.py +47 -0
  256. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/schema_codec.py +145 -0
  257. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/sexp_parser.py +233 -0
  258. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/signal_detectors.py +4699 -0
  259. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/summarize_findings.py +421 -0
  260. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/validation_detectors.py +1440 -0
  261. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/kicad/scripts/what_if.py +1554 -0
  262. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/lcsc/SKILL.md +241 -0
  263. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/lcsc/scripts/fetch_datasheet_lcsc.py +591 -0
  264. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/lcsc/scripts/search_lcsc.py +360 -0
  265. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/lcsc/scripts/sync_datasheets_lcsc.py +755 -0
  266. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/lcsc/scripts/test_search_lcsc.py +358 -0
  267. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/mouser/SKILL.md +265 -0
  268. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/mouser/scripts/fetch_datasheet_mouser.py +600 -0
  269. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/mouser/scripts/sync_datasheets_mouser.py +805 -0
  270. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/pcbway/SKILL.md +179 -0
  271. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/spice/SKILL.md +333 -0
  272. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/spice/references/simulation-models.md +427 -0
  273. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/spice/scripts/__pycache__/spice_model_generator.cpython-314.pyc +0 -0
  274. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/spice/scripts/__pycache__/spice_models.cpython-314.pyc +0 -0
  275. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/spice/scripts/extract_parasitics.py +319 -0
  276. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/spice/scripts/simulate_subcircuits.py +689 -0
  277. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/spice/scripts/spice_model_cache.py +293 -0
  278. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/spice/scripts/spice_model_generator.py +231 -0
  279. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/spice/scripts/spice_models.py +196 -0
  280. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/spice/scripts/spice_part_library.py +447 -0
  281. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/spice/scripts/spice_results.py +1260 -0
  282. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/spice/scripts/spice_simulator.py +475 -0
  283. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/spice/scripts/spice_spec_fetcher.py +650 -0
  284. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/spice/scripts/spice_templates.py +1740 -0
  285. boardforge-0.1.0/src/boardforge/vendor/kicad_happy/skills/spice/scripts/spice_tolerance.py +311 -0
  286. boardforge-0.1.0/src/boardforge.egg-info/PKG-INFO +258 -0
  287. boardforge-0.1.0/src/boardforge.egg-info/SOURCES.txt +299 -0
  288. boardforge-0.1.0/src/boardforge.egg-info/dependency_links.txt +1 -0
  289. boardforge-0.1.0/src/boardforge.egg-info/entry_points.txt +2 -0
  290. boardforge-0.1.0/src/boardforge.egg-info/requires.txt +9 -0
  291. boardforge-0.1.0/src/boardforge.egg-info/top_level.txt +1 -0
  292. boardforge-0.1.0/test/test_bom_check.py +71 -0
  293. boardforge-0.1.0/test/test_budget.py +65 -0
  294. boardforge-0.1.0/test/test_datasheet_check.py +105 -0
  295. boardforge-0.1.0/test/test_datasheets.py +178 -0
  296. boardforge-0.1.0/test/test_fab_outputs.py +40 -0
  297. boardforge-0.1.0/test/test_package_check.py +120 -0
  298. boardforge-0.1.0/test/test_pipeline.py +164 -0
  299. boardforge-0.1.0/test/test_review.py +148 -0
  300. boardforge-0.1.0/test/test_runner_order.py +29 -0
  301. boardforge-0.1.0/test/test_units.py +426 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Dave Vandenbout
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,258 @@
1
+ Metadata-Version: 2.4
2
+ Name: boardforge
3
+ Version: 0.1.0
4
+ Summary: Turn a SKiDL circuit into a routed, manufacturable KiCad board, headless.
5
+ Author-email: Dave Vandenbout <dave@vdb.name>
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/devbisme/boardforge
8
+ Project-URL: Repository, https://github.com/devbisme/boardforge
9
+ Project-URL: Issues, https://github.com/devbisme/boardforge/issues
10
+ Keywords: KiCad,PCB,SKiDL,EDA,routing
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Programming Language :: Python :: 3 :: Only
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: Python :: 3.13
16
+ Classifier: Programming Language :: Python :: 3.14
17
+ Classifier: Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)
18
+ Requires-Python: >=3.11
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE
21
+ Requires-Dist: skidl>=3.0.0
22
+ Requires-Dist: schematizer>=0.2.0
23
+ Provides-Extra: test
24
+ Requires-Dist: pytest; extra == "test"
25
+ Provides-Extra: analysis
26
+ Requires-Dist: jsonschema; extra == "analysis"
27
+ Requires-Dist: referencing; extra == "analysis"
28
+ Dynamic: license-file
29
+
30
+ # boardforge
31
+
32
+ Generate and analyze KiCad designs from a requirements prompt: explore many candidate
33
+ architectures, then turn the selected one into a routed, manufacturable board. SKiDL code is
34
+ the source of truth; runs headless (KiCad only for viewing/editing results).
35
+
36
+ This project was called **boardsmith** until 2026-10-16; the name is taken on PyPI by an
37
+ unrelated tool. An old `boardsmith.toml` is still read (with a warning), and old
38
+ `constraints.json` files keep working.
39
+
40
+ **Status:** the physical pipeline (C1–C6: SKiDL → schematic → board → placement → routing →
41
+ checks → fab outputs) and the review gate (B4) work. The detail stage's agents are a Claude
42
+ Code plugin ([`plugin/`](plugin/README.md)), run end to end twice on the dual-ADC design. The explore stage is not
43
+ started. Design: [`docsrc/design.md`](docsrc/design.md).
44
+
45
+ ## Install
46
+ boardforge needs Python 3.11 or later and these released tools:
47
+
48
+ | Tool | Version | Needed for |
49
+ |---|---|---|
50
+ | [KiCad](https://www.kicad.org/download/) | 10.0 (tested with 10.0.4) | everything: `kicad-cli` and KiCad's Python (`pcbnew`) |
51
+ | [Freerouting](https://github.com/freerouting/freerouting/releases) | 2.4 or later (tested with 2.4.1) | routing (optional: the built-in A* router handles small boards alone) |
52
+ | [ngspice](https://ngspice.sourceforge.io/download.html) | 44 or later (tested with 44.2) | the review gate's simulation checks (optional) |
53
+ | pdftotext ([Poppler](https://poppler.freedesktop.org/) utilities) | any | checking that a downloaded datasheet is the right part (optional) |
54
+
55
+ Install boardforge from PyPI. This also installs [SKiDL](https://pypi.org/project/skidl/)
56
+ 3.0.0 or later and [schematizer](https://pypi.org/project/schematizer/) 0.2.0 or later:
57
+ ```bash
58
+ uv tool install "boardforge[analysis]" # or: pip install "boardforge[analysis]"
59
+ boardforge doctor # checks KiCad 10, its Python, Freerouting, ngspice
60
+ ```
61
+ The `analysis` extra adds `jsonschema`, which validates datasheet extractions.
62
+
63
+ `boardforge doctor` finds KiCad and Freerouting in their usual install locations and on
64
+ `PATH`. Otherwise, set their paths in `~/.config/boardforge/config.toml`, using the same
65
+ `[kicad]` and `[routing.freerouting]` keys as a project file:
66
+ ```toml
67
+ [kicad]
68
+ cli = "/opt/kicad/bin/kicad-cli"
69
+ python = "/opt/kicad/bin/python3"
70
+
71
+ [routing.freerouting]
72
+ path = "/opt/freerouting/bin/freerouting"
73
+ ```
74
+
75
+ To design with Claude Code agents, also install the boardforge plugin
76
+ ([`plugin/README.md`](plugin/README.md)).
77
+
78
+ ## Use
79
+ A project is a directory with a SKiDL file and a `boardforge.toml`:
80
+ ```bash
81
+ cd test/examples/tiny
82
+ boardforge run # C1..C6 -> build/
83
+ boardforge run --from c4 # rerun from routing
84
+ boardforge route # one stage: sch | board | place | route | check | fab
85
+ boardforge status
86
+ boardforge render --side both # build/renders/*.svg/png of the current board
87
+ boardforge review # B4: constraints.json against the design (after C1)
88
+ boardforge datasheets sync # part-fact cache: datasheet PDFs and extractions
89
+ ```
90
+ C3 places multi-pin parts next to what they connect to (through up to three series
91
+ passives), and warns when a connector's signal reaches its first IC from more than
92
+ `[placement] connector_path_mm` (25) away, such as an unbuffered input crossing the board.
93
+ C3 also reports a routability estimate (`reports/congestion.json`: routing demand per 2.5 mm
94
+ cell, ratsnest crossings) and, with compaction, the sizes it tried (`reports/compaction.json`). Each stage prints a short summary; details go to `build/reports/`, and
95
+ `build/pipeline_state.json` records every stage. Outputs:
96
+ - `build/kicad/`: KiCad project (labels-only schematic, board, net classes, lib tables)
97
+ - `build/fab/`: Gerber zip, JLCPCB BOM and CPL
98
+ - `build/docs/`: schematic PDF, 3D renders
99
+ - `build/reports/`: parity, ERC, DRC, geometry checks, kicad-happy analyses
100
+
101
+ ### SKiDL conventions
102
+ - Use `part.fields["MPN"] = ...` (and `LCSC`, `Manufacturer`, `Tolerance`, ...). Keyword
103
+ arguments to `Part()` and plain attributes (`part.MPN = ...`) don't become fields.
104
+ - Net classes: `NetClass("Power", track_width=0.3, clearance=0.15, priority=2)` and
105
+ `net.netclasses = power` (not `net.netclass`, which does nothing). Keys are KiCad's
106
+ `.kicad_pro` names; in SKiDL the larger `priority` wins.
107
+ - Don't set `lib_search_paths`; boardforge points SKiDL at KiCad 10's libraries.
108
+ - Expose a function that builds the circuit and name it in `[design] top`, or build it at
109
+ import time. `[design] file` may also be a package directory (`circuits/<name>/` with
110
+ `__main__.py`); it runs as a module, so relative imports work. The project directory and
111
+ its `symbols/` are on SKiDL's library path.
112
+
113
+ ### boardforge.toml
114
+ See `src/boardforge/config.py` for every key and its default. The main ones:
115
+ ```toml
116
+ [design]
117
+ file = "tiny.py"
118
+ top = "build" # function that builds the circuit
119
+
120
+ [fab]
121
+ name = "jlcpcb"
122
+ tier = "standard" # profile tier: standard (1-2 layers) | multilayer
123
+
124
+ [board]
125
+ size = [130, 90] # mm; omit to estimate from courtyard area (fill)
126
+ layers = 4
127
+ planes = { "In1.Cu" = "GND", "In2.Cu" = "+3V3" }
128
+ pours = ["GND"] # outer-layer pours, stitched with vias
129
+
130
+ [rules] # default net class; lowered to the pad gap of a finer-pitch
131
+ track_width = 0.15 # footprint (0.4 mm QFN: 0.10), down to the fab tier minimum
132
+ clearance = 0.15
133
+
134
+ [[placement.anchor]] # floorplan: fixed positions (mm from top-left)
135
+ value = "^LTC2291" # regex on value (or ref = "U3"), optional sheet regex
136
+ at = [55.0, 44.0]
137
+ rot = 0
138
+ edge = "left" # optional: keep the offset from this edge when compacting
139
+
140
+ [[placement.anchor]] # a connector: rotation from the footprint, mating side out
141
+ ref = "J2"
142
+ at = [12.5, 22.0]
143
+ facing = "left"
144
+ edge = "left"
145
+
146
+ [placement.compact] # shrink the board while everything still fits, then
147
+ enabled = true # confirm by routing (stepping back up if it fails)
148
+ min_scale = 0.6
149
+ max_stretched = 5 # stop when 5 more passives than at full size end up
150
+ stretch_mm = 8.0 # over 8 mm from their spot (C3 summary: stretch)
151
+
152
+ [[placement.region]] # floorplan: unanchored ICs of a sheet go in this area, near
153
+ sheet = "front_end" # the parts they connect to; regex on sheet (and/or value);
154
+ area = [0.0, 0.0, 0.4, 1.0] # fractions of the board (or rect = [x0, y0, x1, y1] mm)
155
+
156
+ [[placement.pin_swap]] # FPGA/MCU pin swap; C3 writes the map, the design reads it
157
+ part = "^ICE40"
158
+ map = "fpga_pinmap.json" # {SKiDL net: pin}; C1-C3 rerun when it changes
159
+ [[placement.pin_swap.group]]
160
+ pins = [1, 2, 3, 4, 7, 8] # swappable pins
161
+ partner = "^LTC2291" # the part these signals go to
162
+
163
+ [routing]
164
+ chain = ["freerouting", "astar"]
165
+ preroute = ["USB_DP", "USB_DM"]
166
+
167
+ [checks.rail_currents] # regulator loads (A) for the thermal check, overriding
168
+ "+1V2" = 0.05 # constraints.json rail_current; else kicad-happy guesses
169
+ ```
170
+ Net names in the config are SKiDL names; boardforge maps them to KiCad's.
171
+
172
+ ### Review gate (B4)
173
+ `boardforge review` checks `constraints.json` (project root) against the design after C1 and
174
+ writes `build/reports/review.json`: PASS / FAIL / NOT CHECKED per constraint. A HARD failure
175
+ fails the gate; SOFT and ASSUMED failures, and anything not checked, warn.
176
+ ```json
177
+ {"schema": "boardforge-constraints", "version": 1, "constraints": [
178
+ {"id": "ALIAS-A", "kind": "ac_gain", "tag": "ASSUMED", "why": "content at Nyquist 40 dB down",
179
+ "in": "VIN_A", "out": ["AIN_AP", "AIN_AN"], "at_hz": 5e6, "ref_hz": 1e3, "max_db": -40}]}
180
+ ```
181
+ `ac_gain` runs an ngspice testbench of the whole path, built from the SKiDL netlist. Op-amps
182
+ and fully-differential amplifiers need a model (unmodelled ICs are open circuits):
183
+ ```toml
184
+ [review]
185
+ dc = { VCM = 0.9 } # DC volts for nets the netlist can't give
186
+ [review.models."^THS4521"] # regex on value / MPN / symbol
187
+ type = "fda" # or "opamp"
188
+ gbw_hz = 93e6 # overridden by a part-fact cache extraction
189
+ pins = { outp = 4, outn = 5 } # roles the symbol's pin names don't give
190
+ ```
191
+ `rail_current` (`net`, `max_a`: the load on the rail) is checked against the rated output
192
+ current (`regulator.iout_max`) of the part that makes the rail, found by its power-output pin
193
+ on the net or behind one series inductor or ferrite bead. The same loads feed the C5 thermal
194
+ check.
195
+ `review` also checks each part that has a datasheet extraction (see Part-fact cache), as
196
+ `DS:<MPN>`: the voltage across its supply pins against the absolute maximum (error) and
197
+ recommended range (warning), and its datasheet power pins connected. `DS:coverage` lists the
198
+ parts without an extraction. `PKG:pins` checks that every symbol pin on a net has a footprint
199
+ pad (and every numbered pad has a pin), and `PKG:<MPN>` compares the footprint with the
200
+ datasheet package: pad count, pitch, thermal pad, pin numbers and body size. `BOM` diffs the
201
+ sourced BOM (`[review] bom`, default `sourcing/sourced_bom.csv`) against the design: MPN,
202
+ LCSC number, value (numerically), footprint, symbol, and the `package` column against the
203
+ footprint's body variant.
204
+
205
+ ### Part-fact cache
206
+ Datasheet PDFs and their structured extractions, in kicad-happy's layout
207
+ (`datasheets/manifest.json`, `<MPN>.pdf`, `extracted/<MPN>.json`), kept twice: in the project
208
+ (`datasheets/`, what the analyzers and `review` read) and in a cache shared by all projects
209
+ (`~/.cache/boardforge/datasheets/`). Parts are the netlist's `MPN` fields; ICs, diodes and
210
+ crystals by default (`prefixes`).
211
+ ```bash
212
+ boardforge datasheets status # per part: PDF, extraction, quality, staleness, in the cache
213
+ boardforge datasheets sync # copy from the shared cache, then find missing PDFs
214
+ boardforge datasheets add MPN FILE_OR_URL # one PDF, after checking it names the part
215
+ boardforge datasheets check MPN... # validate extractions, fill derived fields, score
216
+ boardforge datasheets show MPN... # markdown summary of extractions
217
+ boardforge datasheets paths # kicad-happy's extraction prompts, schemas, examples
218
+ boardforge datasheets publish # copy the project's extractions to the shared cache
219
+ ```
220
+ Before there is a netlist, the parts come from the sourced BOM CSV.
221
+ A PDF is kept only if its text names the part; a scanned one needs `add --force` after a
222
+ look by eye. `sync` looks for a missing PDF in the `search` directories (a file named after the part,
223
+ `OPA810.pdf` for `OPA810IDR`), then downloads it from the symbol's datasheet URL, then
224
+ LCSC. A download whose text doesn't name the part is discarded (needs `pdftotext`). `--fresh`
225
+ skips the shared cache, `--offline` the downloads. Extraction itself is LLM work: an agent
226
+ writes `extracted/<MPN>.json` following kicad-happy's prompts and schemas (`paths`), then
227
+ `check` validates it and fills in the PDF hash, page count and quality score. `publish` takes
228
+ only extractions that match their PDF and pass kicad-happy's schema (needs `jsonschema`), and
229
+ keeps a shared entry unless the project's is newer and scores no lower (`--force`).
230
+ `review` takes op-amp GBW and slew rate from the extractions.
231
+ ```toml
232
+ [datasheets]
233
+ search = ["~/datasheets"]
234
+ cache = "~/.cache/boardforge/datasheets" # "" = no shared cache
235
+ ```
236
+
237
+ ## Layout
238
+ ```
239
+ src/boardforge/ package
240
+ physical.py C1-C6 orchestration
241
+ pcb/ board scripts run under KiCad's Python (all pcbnew code is here)
242
+ routers/ router interface: Freerouting (Specctra), A*
243
+ fabs/<fab>/ fab adapters: profile.toml + adapter
244
+ analysis/ analysis-step registry (kicad-happy analyzers by default)
245
+ review/ B4 gate: constraints.json, SPICE path testbenches, datasheet, package and BOM checks
246
+ datasheets.py part-fact cache: status, sync, add, check, show, publish
247
+ plugin/ Claude Code plugin: the detail-stage agents and skills (from skidl-skills)
248
+ vendor/kicad_happy/ vendored kicad-happy (MIT)
249
+ test/ pytest; test/examples/ has the tiny and dual-ADC projects
250
+ docsrc/ documentation source (design doc)
251
+ ```
252
+ Tests: `pytest -m "not kicad"` for the fast ones; `pytest` also runs the tiny design
253
+ end to end (about a minute).
254
+
255
+ ## Third-party code
256
+ `src/boardforge/vendor/` contains code from other projects, each under its own license.
257
+ See [`src/boardforge/vendor/README.md`](src/boardforge/vendor/README.md). The plugin is
258
+ adapted from skidl-skills (MIT): [`plugin/ATTRIBUTION.md`](plugin/ATTRIBUTION.md).
@@ -0,0 +1,229 @@
1
+ # boardforge
2
+
3
+ Generate and analyze KiCad designs from a requirements prompt: explore many candidate
4
+ architectures, then turn the selected one into a routed, manufacturable board. SKiDL code is
5
+ the source of truth; runs headless (KiCad only for viewing/editing results).
6
+
7
+ This project was called **boardsmith** until 2026-10-16; the name is taken on PyPI by an
8
+ unrelated tool. An old `boardsmith.toml` is still read (with a warning), and old
9
+ `constraints.json` files keep working.
10
+
11
+ **Status:** the physical pipeline (C1–C6: SKiDL → schematic → board → placement → routing →
12
+ checks → fab outputs) and the review gate (B4) work. The detail stage's agents are a Claude
13
+ Code plugin ([`plugin/`](plugin/README.md)), run end to end twice on the dual-ADC design. The explore stage is not
14
+ started. Design: [`docsrc/design.md`](docsrc/design.md).
15
+
16
+ ## Install
17
+ boardforge needs Python 3.11 or later and these released tools:
18
+
19
+ | Tool | Version | Needed for |
20
+ |---|---|---|
21
+ | [KiCad](https://www.kicad.org/download/) | 10.0 (tested with 10.0.4) | everything: `kicad-cli` and KiCad's Python (`pcbnew`) |
22
+ | [Freerouting](https://github.com/freerouting/freerouting/releases) | 2.4 or later (tested with 2.4.1) | routing (optional: the built-in A* router handles small boards alone) |
23
+ | [ngspice](https://ngspice.sourceforge.io/download.html) | 44 or later (tested with 44.2) | the review gate's simulation checks (optional) |
24
+ | pdftotext ([Poppler](https://poppler.freedesktop.org/) utilities) | any | checking that a downloaded datasheet is the right part (optional) |
25
+
26
+ Install boardforge from PyPI. This also installs [SKiDL](https://pypi.org/project/skidl/)
27
+ 3.0.0 or later and [schematizer](https://pypi.org/project/schematizer/) 0.2.0 or later:
28
+ ```bash
29
+ uv tool install "boardforge[analysis]" # or: pip install "boardforge[analysis]"
30
+ boardforge doctor # checks KiCad 10, its Python, Freerouting, ngspice
31
+ ```
32
+ The `analysis` extra adds `jsonschema`, which validates datasheet extractions.
33
+
34
+ `boardforge doctor` finds KiCad and Freerouting in their usual install locations and on
35
+ `PATH`. Otherwise, set their paths in `~/.config/boardforge/config.toml`, using the same
36
+ `[kicad]` and `[routing.freerouting]` keys as a project file:
37
+ ```toml
38
+ [kicad]
39
+ cli = "/opt/kicad/bin/kicad-cli"
40
+ python = "/opt/kicad/bin/python3"
41
+
42
+ [routing.freerouting]
43
+ path = "/opt/freerouting/bin/freerouting"
44
+ ```
45
+
46
+ To design with Claude Code agents, also install the boardforge plugin
47
+ ([`plugin/README.md`](plugin/README.md)).
48
+
49
+ ## Use
50
+ A project is a directory with a SKiDL file and a `boardforge.toml`:
51
+ ```bash
52
+ cd test/examples/tiny
53
+ boardforge run # C1..C6 -> build/
54
+ boardforge run --from c4 # rerun from routing
55
+ boardforge route # one stage: sch | board | place | route | check | fab
56
+ boardforge status
57
+ boardforge render --side both # build/renders/*.svg/png of the current board
58
+ boardforge review # B4: constraints.json against the design (after C1)
59
+ boardforge datasheets sync # part-fact cache: datasheet PDFs and extractions
60
+ ```
61
+ C3 places multi-pin parts next to what they connect to (through up to three series
62
+ passives), and warns when a connector's signal reaches its first IC from more than
63
+ `[placement] connector_path_mm` (25) away, such as an unbuffered input crossing the board.
64
+ C3 also reports a routability estimate (`reports/congestion.json`: routing demand per 2.5 mm
65
+ cell, ratsnest crossings) and, with compaction, the sizes it tried (`reports/compaction.json`). Each stage prints a short summary; details go to `build/reports/`, and
66
+ `build/pipeline_state.json` records every stage. Outputs:
67
+ - `build/kicad/`: KiCad project (labels-only schematic, board, net classes, lib tables)
68
+ - `build/fab/`: Gerber zip, JLCPCB BOM and CPL
69
+ - `build/docs/`: schematic PDF, 3D renders
70
+ - `build/reports/`: parity, ERC, DRC, geometry checks, kicad-happy analyses
71
+
72
+ ### SKiDL conventions
73
+ - Use `part.fields["MPN"] = ...` (and `LCSC`, `Manufacturer`, `Tolerance`, ...). Keyword
74
+ arguments to `Part()` and plain attributes (`part.MPN = ...`) don't become fields.
75
+ - Net classes: `NetClass("Power", track_width=0.3, clearance=0.15, priority=2)` and
76
+ `net.netclasses = power` (not `net.netclass`, which does nothing). Keys are KiCad's
77
+ `.kicad_pro` names; in SKiDL the larger `priority` wins.
78
+ - Don't set `lib_search_paths`; boardforge points SKiDL at KiCad 10's libraries.
79
+ - Expose a function that builds the circuit and name it in `[design] top`, or build it at
80
+ import time. `[design] file` may also be a package directory (`circuits/<name>/` with
81
+ `__main__.py`); it runs as a module, so relative imports work. The project directory and
82
+ its `symbols/` are on SKiDL's library path.
83
+
84
+ ### boardforge.toml
85
+ See `src/boardforge/config.py` for every key and its default. The main ones:
86
+ ```toml
87
+ [design]
88
+ file = "tiny.py"
89
+ top = "build" # function that builds the circuit
90
+
91
+ [fab]
92
+ name = "jlcpcb"
93
+ tier = "standard" # profile tier: standard (1-2 layers) | multilayer
94
+
95
+ [board]
96
+ size = [130, 90] # mm; omit to estimate from courtyard area (fill)
97
+ layers = 4
98
+ planes = { "In1.Cu" = "GND", "In2.Cu" = "+3V3" }
99
+ pours = ["GND"] # outer-layer pours, stitched with vias
100
+
101
+ [rules] # default net class; lowered to the pad gap of a finer-pitch
102
+ track_width = 0.15 # footprint (0.4 mm QFN: 0.10), down to the fab tier minimum
103
+ clearance = 0.15
104
+
105
+ [[placement.anchor]] # floorplan: fixed positions (mm from top-left)
106
+ value = "^LTC2291" # regex on value (or ref = "U3"), optional sheet regex
107
+ at = [55.0, 44.0]
108
+ rot = 0
109
+ edge = "left" # optional: keep the offset from this edge when compacting
110
+
111
+ [[placement.anchor]] # a connector: rotation from the footprint, mating side out
112
+ ref = "J2"
113
+ at = [12.5, 22.0]
114
+ facing = "left"
115
+ edge = "left"
116
+
117
+ [placement.compact] # shrink the board while everything still fits, then
118
+ enabled = true # confirm by routing (stepping back up if it fails)
119
+ min_scale = 0.6
120
+ max_stretched = 5 # stop when 5 more passives than at full size end up
121
+ stretch_mm = 8.0 # over 8 mm from their spot (C3 summary: stretch)
122
+
123
+ [[placement.region]] # floorplan: unanchored ICs of a sheet go in this area, near
124
+ sheet = "front_end" # the parts they connect to; regex on sheet (and/or value);
125
+ area = [0.0, 0.0, 0.4, 1.0] # fractions of the board (or rect = [x0, y0, x1, y1] mm)
126
+
127
+ [[placement.pin_swap]] # FPGA/MCU pin swap; C3 writes the map, the design reads it
128
+ part = "^ICE40"
129
+ map = "fpga_pinmap.json" # {SKiDL net: pin}; C1-C3 rerun when it changes
130
+ [[placement.pin_swap.group]]
131
+ pins = [1, 2, 3, 4, 7, 8] # swappable pins
132
+ partner = "^LTC2291" # the part these signals go to
133
+
134
+ [routing]
135
+ chain = ["freerouting", "astar"]
136
+ preroute = ["USB_DP", "USB_DM"]
137
+
138
+ [checks.rail_currents] # regulator loads (A) for the thermal check, overriding
139
+ "+1V2" = 0.05 # constraints.json rail_current; else kicad-happy guesses
140
+ ```
141
+ Net names in the config are SKiDL names; boardforge maps them to KiCad's.
142
+
143
+ ### Review gate (B4)
144
+ `boardforge review` checks `constraints.json` (project root) against the design after C1 and
145
+ writes `build/reports/review.json`: PASS / FAIL / NOT CHECKED per constraint. A HARD failure
146
+ fails the gate; SOFT and ASSUMED failures, and anything not checked, warn.
147
+ ```json
148
+ {"schema": "boardforge-constraints", "version": 1, "constraints": [
149
+ {"id": "ALIAS-A", "kind": "ac_gain", "tag": "ASSUMED", "why": "content at Nyquist 40 dB down",
150
+ "in": "VIN_A", "out": ["AIN_AP", "AIN_AN"], "at_hz": 5e6, "ref_hz": 1e3, "max_db": -40}]}
151
+ ```
152
+ `ac_gain` runs an ngspice testbench of the whole path, built from the SKiDL netlist. Op-amps
153
+ and fully-differential amplifiers need a model (unmodelled ICs are open circuits):
154
+ ```toml
155
+ [review]
156
+ dc = { VCM = 0.9 } # DC volts for nets the netlist can't give
157
+ [review.models."^THS4521"] # regex on value / MPN / symbol
158
+ type = "fda" # or "opamp"
159
+ gbw_hz = 93e6 # overridden by a part-fact cache extraction
160
+ pins = { outp = 4, outn = 5 } # roles the symbol's pin names don't give
161
+ ```
162
+ `rail_current` (`net`, `max_a`: the load on the rail) is checked against the rated output
163
+ current (`regulator.iout_max`) of the part that makes the rail, found by its power-output pin
164
+ on the net or behind one series inductor or ferrite bead. The same loads feed the C5 thermal
165
+ check.
166
+ `review` also checks each part that has a datasheet extraction (see Part-fact cache), as
167
+ `DS:<MPN>`: the voltage across its supply pins against the absolute maximum (error) and
168
+ recommended range (warning), and its datasheet power pins connected. `DS:coverage` lists the
169
+ parts without an extraction. `PKG:pins` checks that every symbol pin on a net has a footprint
170
+ pad (and every numbered pad has a pin), and `PKG:<MPN>` compares the footprint with the
171
+ datasheet package: pad count, pitch, thermal pad, pin numbers and body size. `BOM` diffs the
172
+ sourced BOM (`[review] bom`, default `sourcing/sourced_bom.csv`) against the design: MPN,
173
+ LCSC number, value (numerically), footprint, symbol, and the `package` column against the
174
+ footprint's body variant.
175
+
176
+ ### Part-fact cache
177
+ Datasheet PDFs and their structured extractions, in kicad-happy's layout
178
+ (`datasheets/manifest.json`, `<MPN>.pdf`, `extracted/<MPN>.json`), kept twice: in the project
179
+ (`datasheets/`, what the analyzers and `review` read) and in a cache shared by all projects
180
+ (`~/.cache/boardforge/datasheets/`). Parts are the netlist's `MPN` fields; ICs, diodes and
181
+ crystals by default (`prefixes`).
182
+ ```bash
183
+ boardforge datasheets status # per part: PDF, extraction, quality, staleness, in the cache
184
+ boardforge datasheets sync # copy from the shared cache, then find missing PDFs
185
+ boardforge datasheets add MPN FILE_OR_URL # one PDF, after checking it names the part
186
+ boardforge datasheets check MPN... # validate extractions, fill derived fields, score
187
+ boardforge datasheets show MPN... # markdown summary of extractions
188
+ boardforge datasheets paths # kicad-happy's extraction prompts, schemas, examples
189
+ boardforge datasheets publish # copy the project's extractions to the shared cache
190
+ ```
191
+ Before there is a netlist, the parts come from the sourced BOM CSV.
192
+ A PDF is kept only if its text names the part; a scanned one needs `add --force` after a
193
+ look by eye. `sync` looks for a missing PDF in the `search` directories (a file named after the part,
194
+ `OPA810.pdf` for `OPA810IDR`), then downloads it from the symbol's datasheet URL, then
195
+ LCSC. A download whose text doesn't name the part is discarded (needs `pdftotext`). `--fresh`
196
+ skips the shared cache, `--offline` the downloads. Extraction itself is LLM work: an agent
197
+ writes `extracted/<MPN>.json` following kicad-happy's prompts and schemas (`paths`), then
198
+ `check` validates it and fills in the PDF hash, page count and quality score. `publish` takes
199
+ only extractions that match their PDF and pass kicad-happy's schema (needs `jsonschema`), and
200
+ keeps a shared entry unless the project's is newer and scores no lower (`--force`).
201
+ `review` takes op-amp GBW and slew rate from the extractions.
202
+ ```toml
203
+ [datasheets]
204
+ search = ["~/datasheets"]
205
+ cache = "~/.cache/boardforge/datasheets" # "" = no shared cache
206
+ ```
207
+
208
+ ## Layout
209
+ ```
210
+ src/boardforge/ package
211
+ physical.py C1-C6 orchestration
212
+ pcb/ board scripts run under KiCad's Python (all pcbnew code is here)
213
+ routers/ router interface: Freerouting (Specctra), A*
214
+ fabs/<fab>/ fab adapters: profile.toml + adapter
215
+ analysis/ analysis-step registry (kicad-happy analyzers by default)
216
+ review/ B4 gate: constraints.json, SPICE path testbenches, datasheet, package and BOM checks
217
+ datasheets.py part-fact cache: status, sync, add, check, show, publish
218
+ plugin/ Claude Code plugin: the detail-stage agents and skills (from skidl-skills)
219
+ vendor/kicad_happy/ vendored kicad-happy (MIT)
220
+ test/ pytest; test/examples/ has the tiny and dual-ADC projects
221
+ docsrc/ documentation source (design doc)
222
+ ```
223
+ Tests: `pytest -m "not kicad"` for the fast ones; `pytest` also runs the tiny design
224
+ end to end (about a minute).
225
+
226
+ ## Third-party code
227
+ `src/boardforge/vendor/` contains code from other projects, each under its own license.
228
+ See [`src/boardforge/vendor/README.md`](src/boardforge/vendor/README.md). The plugin is
229
+ adapted from skidl-skills (MIT): [`plugin/ATTRIBUTION.md`](plugin/ATTRIBUTION.md).
@@ -0,0 +1,60 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "boardforge"
7
+ version = "0.1.0"
8
+ description = "Turn a SKiDL circuit into a routed, manufacturable KiCad board, headless."
9
+ readme = "README.md"
10
+ # tomllib (stdlib) is used for configuration and fab profiles. KiCad 10 ships Python 3.11,
11
+ # and the board scripts in boardforge.pcb run under it, so 3.11 is the floor for both sides.
12
+ requires-python = ">=3.11"
13
+ license = "MIT"
14
+ license-files = ["LICENSE"]
15
+ authors = [{ name = "Dave Vandenbout", email = "dave@vdb.name" }]
16
+ keywords = ["KiCad", "PCB", "SKiDL", "EDA", "routing"]
17
+ classifiers = [
18
+ "Development Status :: 3 - Alpha",
19
+ "Programming Language :: Python :: 3 :: Only",
20
+ "Programming Language :: Python :: 3.11",
21
+ "Programming Language :: Python :: 3.12",
22
+ "Programming Language :: Python :: 3.13",
23
+ "Programming Language :: Python :: 3.14",
24
+ "Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)",
25
+ ]
26
+ # skidl >= 3.0.0 reads KiCad 10 .kicad_symdir libraries and writes the fields, attributes and
27
+ # net classes into its netlist; schematizer >= 0.2.0 has the labels-only schematic mode.
28
+ dependencies = [
29
+ "skidl>=3.0.0",
30
+ "schematizer>=0.2.0",
31
+ ]
32
+
33
+ [project.urls]
34
+ Homepage = "https://github.com/devbisme/boardforge"
35
+ Repository = "https://github.com/devbisme/boardforge"
36
+ Issues = "https://github.com/devbisme/boardforge/issues"
37
+
38
+ [project.optional-dependencies]
39
+ test = ["pytest"]
40
+ # A few vendored kicad-happy validators use these.
41
+ analysis = ["jsonschema", "referencing"]
42
+
43
+ [project.scripts]
44
+ boardforge = "boardforge.cli:main"
45
+
46
+ [tool.setuptools.packages.find]
47
+ where = ["src"]
48
+
49
+ [tool.setuptools.package-data]
50
+ boardforge = ["fabs/*/*.toml", "vendor/**/*"]
51
+
52
+ [tool.pytest.ini_options]
53
+ testpaths = ["test"]
54
+ markers = [
55
+ "kicad: needs KiCad 10 (kicad-cli and its Python)",
56
+ "slow: runs the full pipeline (minutes)",
57
+ ]
58
+
59
+ [tool.black]
60
+ line-length = 100
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,7 @@
1
+ """boardforge: SKiDL circuit -> routed, manufacturable KiCad board.
2
+
3
+ Keep this module free of imports: the scripts in boardforge.pcb run under KiCad's own
4
+ Python, which imports this package but has none of boardforge's dependencies.
5
+ """
6
+
7
+ __version__ = "0.1.0"