@tobisk/pcbs 1.0.0

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 (168) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +186 -0
  3. package/dist/src/cli/cli.d.ts +6 -0
  4. package/dist/src/cli/cli.js +87 -0
  5. package/dist/src/cli/cli.js.map +1 -0
  6. package/dist/src/cli/codegen.d.ts +25 -0
  7. package/dist/src/cli/codegen.js +170 -0
  8. package/dist/src/cli/codegen.js.map +1 -0
  9. package/dist/src/cli/commands/export.d.ts +13 -0
  10. package/dist/src/cli/commands/export.js +301 -0
  11. package/dist/src/cli/commands/export.js.map +1 -0
  12. package/dist/src/cli/commands/lib.d.ts +10 -0
  13. package/dist/src/cli/commands/lib.js +158 -0
  14. package/dist/src/cli/commands/lib.js.map +1 -0
  15. package/dist/src/cli/commands/parts.d.ts +4 -0
  16. package/dist/src/cli/commands/parts.js +104 -0
  17. package/dist/src/cli/commands/parts.js.map +1 -0
  18. package/dist/src/cli/commands/setup.d.ts +4 -0
  19. package/dist/src/cli/commands/setup.js +86 -0
  20. package/dist/src/cli/commands/setup.js.map +1 -0
  21. package/dist/src/cli/commands/synth.d.ts +4 -0
  22. package/dist/src/cli/commands/synth.js +75 -0
  23. package/dist/src/cli/commands/synth.js.map +1 -0
  24. package/dist/src/cli/commands/types.d.ts +1 -0
  25. package/dist/src/cli/commands/types.js +140 -0
  26. package/dist/src/cli/commands/types.js.map +1 -0
  27. package/dist/src/cli/commands/validate.d.ts +5 -0
  28. package/dist/src/cli/commands/validate.js +105 -0
  29. package/dist/src/cli/commands/validate.js.map +1 -0
  30. package/dist/src/cli/config.d.ts +9 -0
  31. package/dist/src/cli/config.js +80 -0
  32. package/dist/src/cli/config.js.map +1 -0
  33. package/dist/src/cli/env.d.ts +4 -0
  34. package/dist/src/cli/env.js +166 -0
  35. package/dist/src/cli/env.js.map +1 -0
  36. package/dist/src/cli/search-jlc.d.ts +0 -0
  37. package/dist/src/cli/search-jlc.js +23 -0
  38. package/dist/src/cli/search-jlc.js.map +1 -0
  39. package/dist/src/cli/synthesis.d.ts +11 -0
  40. package/dist/src/cli/synthesis.js +120 -0
  41. package/dist/src/cli/synthesis.js.map +1 -0
  42. package/dist/src/cli/utils/bom.d.ts +19 -0
  43. package/dist/src/cli/utils/bom.js +130 -0
  44. package/dist/src/cli/utils/bom.js.map +1 -0
  45. package/dist/src/cli/utils/cpl.d.ts +18 -0
  46. package/dist/src/cli/utils/cpl.js +101 -0
  47. package/dist/src/cli/utils/cpl.js.map +1 -0
  48. package/dist/src/cli/utils.d.ts +11 -0
  49. package/dist/src/cli/utils.js +136 -0
  50. package/dist/src/cli/utils.js.map +1 -0
  51. package/dist/src/generate-kicad-types.d.ts +1 -0
  52. package/dist/src/generate-kicad-types.js +137 -0
  53. package/dist/src/generate-kicad-types.js.map +1 -0
  54. package/dist/src/synth/3d/Kicad3DModel.d.ts +81 -0
  55. package/dist/src/synth/3d/Kicad3DModel.js +250 -0
  56. package/dist/src/synth/3d/Kicad3DModel.js.map +1 -0
  57. package/dist/src/synth/3d/booleans.d.ts +10 -0
  58. package/dist/src/synth/3d/booleans.js +30 -0
  59. package/dist/src/synth/3d/booleans.js.map +1 -0
  60. package/dist/src/synth/3d/fillet.d.ts +14 -0
  61. package/dist/src/synth/3d/fillet.js +47 -0
  62. package/dist/src/synth/3d/fillet.js.map +1 -0
  63. package/dist/src/synth/3d/index.d.ts +7 -0
  64. package/dist/src/synth/3d/index.js +14 -0
  65. package/dist/src/synth/3d/index.js.map +1 -0
  66. package/dist/src/synth/3d/occ-loader.d.ts +5 -0
  67. package/dist/src/synth/3d/occ-loader.js +77 -0
  68. package/dist/src/synth/3d/occ-loader.js.map +1 -0
  69. package/dist/src/synth/3d/occ.d.ts +3 -0
  70. package/dist/src/synth/3d/occ.js +31 -0
  71. package/dist/src/synth/3d/occ.js.map +1 -0
  72. package/dist/src/synth/3d/primitives.d.ts +38 -0
  73. package/dist/src/synth/3d/primitives.js +58 -0
  74. package/dist/src/synth/3d/primitives.js.map +1 -0
  75. package/dist/src/synth/3d/stepWriter.d.ts +7 -0
  76. package/dist/src/synth/3d/stepWriter.js +72 -0
  77. package/dist/src/synth/3d/stepWriter.js.map +1 -0
  78. package/dist/src/synth/3d/transforms.d.ts +18 -0
  79. package/dist/src/synth/3d/transforms.js +74 -0
  80. package/dist/src/synth/3d/transforms.js.map +1 -0
  81. package/dist/src/synth/3d/types.d.ts +54 -0
  82. package/dist/src/synth/3d/types.js +21 -0
  83. package/dist/src/synth/3d/types.js.map +1 -0
  84. package/dist/src/synth/3d/vrmlWriter.d.ts +5 -0
  85. package/dist/src/synth/3d/vrmlWriter.js +171 -0
  86. package/dist/src/synth/3d/vrmlWriter.js.map +1 -0
  87. package/dist/src/synth/Component.d.ts +67 -0
  88. package/dist/src/synth/Component.js +185 -0
  89. package/dist/src/synth/Component.js.map +1 -0
  90. package/dist/src/synth/Composable.d.ts +73 -0
  91. package/dist/src/synth/Composable.js +128 -0
  92. package/dist/src/synth/Composable.js.map +1 -0
  93. package/dist/src/synth/KicadFootprint.d.ts +97 -0
  94. package/dist/src/synth/KicadFootprint.js +312 -0
  95. package/dist/src/synth/KicadFootprint.js.map +1 -0
  96. package/dist/src/synth/KicadLibrary.d.ts +66 -0
  97. package/dist/src/synth/KicadLibrary.js +162 -0
  98. package/dist/src/synth/KicadLibrary.js.map +1 -0
  99. package/dist/src/synth/KicadSymbol.d.ts +71 -0
  100. package/dist/src/synth/KicadSymbol.js +190 -0
  101. package/dist/src/synth/KicadSymbol.js.map +1 -0
  102. package/dist/src/synth/Layout.d.ts +37 -0
  103. package/dist/src/synth/Layout.js +58 -0
  104. package/dist/src/synth/Layout.js.map +1 -0
  105. package/dist/src/synth/Markers.d.ts +35 -0
  106. package/dist/src/synth/Markers.js +48 -0
  107. package/dist/src/synth/Markers.js.map +1 -0
  108. package/dist/src/synth/Module.d.ts +56 -0
  109. package/dist/src/synth/Module.js +65 -0
  110. package/dist/src/synth/Module.js.map +1 -0
  111. package/dist/src/synth/Net.d.ts +23 -0
  112. package/dist/src/synth/Net.js +95 -0
  113. package/dist/src/synth/Net.js.map +1 -0
  114. package/dist/src/synth/Registry.d.ts +36 -0
  115. package/dist/src/synth/Registry.js +75 -0
  116. package/dist/src/synth/Registry.js.map +1 -0
  117. package/dist/src/synth/Schematic.d.ts +36 -0
  118. package/dist/src/synth/Schematic.js +51 -0
  119. package/dist/src/synth/Schematic.js.map +1 -0
  120. package/dist/src/synth/index.d.ts +21 -0
  121. package/dist/src/synth/index.js +46 -0
  122. package/dist/src/synth/index.js.map +1 -0
  123. package/dist/src/synth/kicad-types-placeholder.d.ts +6 -0
  124. package/dist/src/synth/kicad-types-placeholder.js +7 -0
  125. package/dist/src/synth/kicad-types-placeholder.js.map +1 -0
  126. package/dist/src/synth/types.d.ts +111 -0
  127. package/dist/src/synth/types.js +23 -0
  128. package/dist/src/synth/types.js.map +1 -0
  129. package/dist/src/tests/3d-model.test.d.ts +1 -0
  130. package/dist/src/tests/3d-model.test.js +282 -0
  131. package/dist/src/tests/3d-model.test.js.map +1 -0
  132. package/dist/src/tests/codegen.test.d.ts +1 -0
  133. package/dist/src/tests/codegen.test.js +80 -0
  134. package/dist/src/tests/codegen.test.js.map +1 -0
  135. package/dist/src/tests/dmx_node.test.d.ts +1 -0
  136. package/dist/src/tests/dmx_node.test.js +42 -0
  137. package/dist/src/tests/dmx_node.test.js.map +1 -0
  138. package/dist/src/tests/dnc.test.d.ts +1 -0
  139. package/dist/src/tests/dnc.test.js +100 -0
  140. package/dist/src/tests/dnc.test.js.map +1 -0
  141. package/dist/src/tests/kicad-lib.test.d.ts +1 -0
  142. package/dist/src/tests/kicad-lib.test.js +465 -0
  143. package/dist/src/tests/kicad-lib.test.js.map +1 -0
  144. package/dist/src/tests/layout.test.d.ts +1 -0
  145. package/dist/src/tests/layout.test.js +92 -0
  146. package/dist/src/tests/layout.test.js.map +1 -0
  147. package/dist/src/tests/migration.test.d.ts +1 -0
  148. package/dist/src/tests/migration.test.js +58 -0
  149. package/dist/src/tests/migration.test.js.map +1 -0
  150. package/dist/src/tests/net_merging.test.d.ts +1 -0
  151. package/dist/src/tests/net_merging.test.js +97 -0
  152. package/dist/src/tests/net_merging.test.js.map +1 -0
  153. package/dist/src/tests/occ-minimal.test.d.ts +1 -0
  154. package/dist/src/tests/occ-minimal.test.js +14 -0
  155. package/dist/src/tests/occ-minimal.test.js.map +1 -0
  156. package/dist/src/tests/placement.test.d.ts +1 -0
  157. package/dist/src/tests/placement.test.js +130 -0
  158. package/dist/src/tests/placement.test.js.map +1 -0
  159. package/dist/src/tests/synthesis.test.d.ts +1 -0
  160. package/dist/src/tests/synthesis.test.js +88 -0
  161. package/dist/src/tests/synthesis.test.js.map +1 -0
  162. package/dist/src/types/kicad-library.d.ts +6 -0
  163. package/dist/src/types/kicad-library.js +7 -0
  164. package/dist/src/types/kicad-library.js.map +1 -0
  165. package/dist/src/types/kicad-library.ts +61770 -0
  166. package/package.json +57 -0
  167. package/scripts/patch-opencascade.ts +18 -0
  168. package/scripts/wasm-stub.js +1 -0
package/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Tobias Keller
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.
package/README.md ADDED
@@ -0,0 +1,186 @@
1
+ # @tobisk/pcbs
2
+
3
+ A strict, type-safe TypeScript framework for designing PCBs, powered by [circuit-synth](https://github.com/circuit-synth/circuit-synth).
4
+
5
+ This is a framework I have built around circuit-synth to better suit my workflow.
6
+
7
+ The problem to solve here is that while circuit-synth is awesome, it only manages circuits and since it's python it's not type safe.
8
+
9
+ I needed a way to also manage custom footprints and ideally generate them by uploading a picture or describing them to the AI.
10
+
11
+ On top of circuit-synth, we have added:
12
+ - Directly export zip files to upload to JLCPCB including the Pick'n'Place csv files
13
+ - add a simple command to let an ai agent search for JLC parts (WIP)
14
+ - Manage Footprints, Symbols
15
+ - Manage 3d visualisations of the footprints
16
+ - Type Safety
17
+
18
+ ## Features
19
+
20
+ - **Type-Safe Design**: leveraging TypeScript to ensure correct connectivity and component logic.
21
+ - **Circuit-Synth Integration**: Uses `circuit-synth` internally for the heavy lifting of netlisting and PCB generation.
22
+ - **Programmatic Layout**: Define schematic and PCB positions in code.
23
+ - **Modular Components**: Reusable `Composable` blocks (e.g., Buck Converters, LED Indicators).
24
+
25
+ ## Usage
26
+
27
+ ```bash
28
+ npm install @tobisk/pcbs
29
+ ```
30
+
31
+ ### CLI
32
+
33
+ ```bash
34
+ npx @tobisk/pcbs synth <schematic-name>
35
+ npx @tobisk/pcbs export <schematic-name>
36
+ npx @tobisk/pcbs lib <schematic-name>
37
+ ```
38
+
39
+ Once you have `synth`-ethized your schematic, you can open the kicad schematic file and generate a PCB from it. Every time we synth, we update the schematic and the netlist.
40
+
41
+ It could be that the internal IDs of the kicad symbols drift, so when loading a new netlist in the PCB editor and the positions change, undo the loading and select the "Match by Reference" and re-import the net.
42
+
43
+ ## Project Structure
44
+
45
+ A typical project using `@tobisk/pcbs` is structured into three main directories:
46
+
47
+ - `src/lib/`: Reusable, technology-independent building blocks (`Composable`).
48
+ - `src/module/`: Physical components or sub-assemblies with specific footprints (`Module`).
49
+ - `src/schematics/`: The top-level design that wires everything together (`Schematic`).
50
+
51
+ ```text
52
+ my-pcb-project/
53
+ ├── src/
54
+ │ ├── lib/ # Reusable Composable blocks
55
+ │ │ └── LedIndicator.ts
56
+ │ ├── module/ # Physical Modules (Symbols + Footprints)
57
+ │ │ └── UsbPowerModule.ts
58
+ │ └── schematics/ # Project Schematics
59
+ │ └── MyProject.ts
60
+ ├── package.json
61
+ └── tsconfig.json
62
+ ```
63
+
64
+ ## Examples
65
+
66
+ ### 1. Composable (Logic Block)
67
+ `Composable` blocks are reusable circuits that define logic and connectivity without being tied to a single physical package.
68
+
69
+ ```typescript
70
+ import { Composable, Net, Component, PinAssignable } from "@tobisk/pcbs";
71
+
72
+ export class LedIndicator extends Composable<"SIGNAL" | "GND"> {
73
+ constructor(options: { ref: string; color?: string }) {
74
+ super({ ref: options.ref });
75
+
76
+ const resistor = new Component({
77
+ symbol: "Device:R",
78
+ footprint: "Resistor_SMD:R_0603_1608Metric",
79
+ value: "330",
80
+ });
81
+
82
+ const led = new Component({
83
+ symbol: "Device:LED",
84
+ footprint: "LED_SMD:LED_0603_1608Metric",
85
+ value: options.color ?? "Green",
86
+ });
87
+
88
+ const internal = new Net();
89
+ internal.tie(resistor.pins[2]);
90
+ internal.tie(led.pins[1]);
91
+
92
+ this.resistor = resistor; // Store for defineInterface
93
+ this.led = led;
94
+ }
95
+
96
+ protected defineInterface(): Record<string, PinAssignable> {
97
+ return {
98
+ SIGNAL: this.resistor.pins[1],
99
+ GND: this.led.pins[2],
100
+ };
101
+ }
102
+ }
103
+ ```
104
+
105
+ ### 2. Module (Physical Component)
106
+ `Module` represents a physical component with a specific KiCad symbol and footprint. It can also define a parametric 3D model.
107
+
108
+ ```typescript
109
+ import { KicadFootprint, KicadSymbol, Module, Kicad3DModel } from "@tobisk/pcbs";
110
+
111
+ export class UsbPowerModule extends Module<"VBUS" | "GND"> {
112
+ constructor(options: { ref?: string }) {
113
+ super({
114
+ symbol: "Project_Symbols:USB_Power_Module",
115
+ footprint: "Project_Footprints:USB_Power_Module",
116
+ ref: options.ref ?? "J_PWR",
117
+ pins: (pin) => ({
118
+ GND: pin(1),
119
+ VBUS: pin(2),
120
+ }),
121
+ });
122
+ }
123
+
124
+ public static makeFootprint(): KicadFootprint {
125
+ const fp = new KicadFootprint({ name: "USB_Power_Module" });
126
+ // ... define pads and graphics ...
127
+ return fp;
128
+ }
129
+
130
+ public static makeSymbol(): KicadSymbol {
131
+ const sym = new KicadSymbol({ name: "USB_Power_Module", reference: "J" });
132
+ // ... define pins and shapes ...
133
+ return sym;
134
+ }
135
+
136
+ public static async make3DModel(): Promise<Kicad3DModel> {
137
+ const model = new Kicad3DModel({ unit: "mm" });
138
+ await model.init();
139
+
140
+ // Box for the connector body
141
+ model.box({ x: 10, y: 15, z: 5, center: true })
142
+ .color("#c0c0c0") // Silver
143
+ .name("body");
144
+
145
+ // Cylindrical pins
146
+ model.cylinder({ r: 0.5, h: 4 })
147
+ .translate({ x: -3, y: 0, z: -2 })
148
+ .color("#ffd700") // Gold
149
+ .name("pin1");
150
+
151
+ return model;
152
+ }
153
+ }
154
+ ```
155
+
156
+ ### 3. Schematic (Top-level Project)
157
+ `Schematic` is where you instantiate modules and composables and wire them together.
158
+
159
+ ```typescript
160
+ import { Schematic, Net } from "@tobisk/pcbs";
161
+ import { LedIndicator } from "../lib/LedIndicator";
162
+ import { UsbPowerModule } from "../module/UsbPowerModule";
163
+
164
+ export class MyProject extends Schematic {
165
+ constructor() {
166
+ super({ name: "My_Cool_PCB" });
167
+ }
168
+
169
+ generate() {
170
+ const gnd = new Net({ name: "GND" });
171
+ const vcc = new Net({ name: "+5V" });
172
+
173
+ const pwr = new UsbPowerModule();
174
+ const statusLed = new LedIndicator({ ref: "STATUS" });
175
+
176
+ // Wiring
177
+ pwr.pins.VBUS = vcc;
178
+ pwr.pins.GND = gnd;
179
+
180
+ statusLed.pins.SIGNAL = vcc;
181
+ statusLed.pins.GND = gnd;
182
+ }
183
+ }
184
+
185
+ export default new MyProject();
186
+ ```
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * PCB Framework CLI
4
+ */
5
+ import "ts-node/register";
6
+ import "tsconfig-paths/register";
@@ -0,0 +1,87 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ /**
4
+ * PCB Framework CLI
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ require("ts-node/register");
8
+ require("tsconfig-paths/register");
9
+ const env_1 = require("./env");
10
+ const synth_1 = require("./commands/synth");
11
+ const export_1 = require("./commands/export");
12
+ const parts_1 = require("./commands/parts");
13
+ const lib_1 = require("./commands/lib");
14
+ const types_1 = require("./commands/types");
15
+ const setup_1 = require("./commands/setup");
16
+ // Parse args for --root early to configure environment
17
+ for (let i = 0; i < process.argv.length; i++) {
18
+ if (process.argv[i] === "--root" && process.argv[i + 1]) {
19
+ process.env.SCHEMATICS_ROOT = process.argv[i + 1];
20
+ break;
21
+ }
22
+ }
23
+ function printHelp() {
24
+ console.log(`
25
+ PCB Framework CLI
26
+
27
+ Usage:
28
+ npx @tobisk/pcbs <command> [options]
29
+
30
+ Commands:
31
+ synth [entry] Synthesize a schematic to KiCad project
32
+ export [entry] Export gerber, BOM, and placement files
33
+ parts [--footprint <fp>] [--value <val>]
34
+ Search JLC Parts for components
35
+ lib [module ...] Generate/update KiCad library from TS modules
36
+ types Sync KiCad library symbols and footprints to TS types
37
+ setup Configure project tsconfig.json for KiCad types
38
+
39
+ Schematic Selection:
40
+ If no entry is provided for synth/export, an interactive list of
41
+ available schematics from src/schematics/ is shown.
42
+
43
+ Examples:
44
+ npx @tobisk/pcbs synth my_board
45
+ npx @tobisk/pcbs synth ./src/schematics/my_board/index.ts
46
+ npx @tobisk/pcbs export my_board
47
+ npx @tobisk/pcbs parts --footprint 0603 --value 10k
48
+ npx @tobisk/pcbs parts
49
+ `);
50
+ }
51
+ async function main() {
52
+ // Ensure dependencies are met before doing anything else
53
+ (0, env_1.ensurePythonEnv)();
54
+ const args = process.argv.slice(2);
55
+ const command = args[0];
56
+ const commandArgs = args.slice(1);
57
+ switch (command) {
58
+ case "synth":
59
+ return (0, synth_1.cmdSynth)(commandArgs);
60
+ case "export":
61
+ return (0, export_1.cmdExport)(commandArgs);
62
+ case "parts":
63
+ return (0, parts_1.cmdParts)(commandArgs);
64
+ case "lib":
65
+ return (0, lib_1.cmdLib)(commandArgs);
66
+ case "types":
67
+ return (0, types_1.cmdTypes)(commandArgs);
68
+ case "setup":
69
+ return (0, setup_1.cmdSetup)(commandArgs);
70
+ case "--help":
71
+ case "-h":
72
+ case "help":
73
+ printHelp();
74
+ break;
75
+ default:
76
+ if (command) {
77
+ console.error(`Unknown command: ${command}\n`);
78
+ }
79
+ printHelp();
80
+ process.exit(command ? 1 : 0);
81
+ }
82
+ }
83
+ main().catch((err) => {
84
+ console.error(err);
85
+ process.exit(1);
86
+ });
87
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../../src/cli/cli.ts"],"names":[],"mappings":";;AAEA;;GAEG;;AAEH,4BAA0B;AAC1B,mCAAiC;AACjC,+BAAwC;AACxC,4CAA4C;AAC5C,8CAA8C;AAC9C,4CAA4C;AAC5C,wCAAwC;AACxC,4CAA4C;AAC5C,4CAA4C;AAE5C,uDAAuD;AACvD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;IAC7C,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;QACxD,OAAO,CAAC,GAAG,CAAC,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAClD,MAAM;IACR,CAAC;AACH,CAAC;AAED,SAAS,SAAS;IAChB,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;CAyBb,CAAC,CAAC;AACH,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,yDAAyD;IACzD,IAAA,qBAAe,GAAE,CAAC;IAElB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,OAAO,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACxB,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAElC,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,OAAO;YACV,OAAO,IAAA,gBAAQ,EAAC,WAAW,CAAC,CAAC;QAC/B,KAAK,QAAQ;YACX,OAAO,IAAA,kBAAS,EAAC,WAAW,CAAC,CAAC;QAChC,KAAK,OAAO;YACV,OAAO,IAAA,gBAAQ,EAAC,WAAW,CAAC,CAAC;QAC/B,KAAK,KAAK;YACR,OAAO,IAAA,YAAM,EAAC,WAAW,CAAC,CAAC;QAC7B,KAAK,OAAO;YACV,OAAO,IAAA,gBAAQ,EAAC,WAAW,CAAC,CAAC;QAC/B,KAAK,OAAO;YACV,OAAO,IAAA,gBAAQ,EAAC,WAAW,CAAC,CAAC;QAC/B,KAAK,QAAQ,CAAC;QACd,KAAK,IAAI,CAAC;QACV,KAAK,MAAM;YACT,SAAS,EAAE,CAAC;YACZ,MAAM;QACR;YACE,IAAI,OAAO,EAAE,CAAC;gBACZ,OAAO,CAAC,KAAK,CAAC,oBAAoB,OAAO,IAAI,CAAC,CAAC;YACjD,CAAC;YACD,SAAS,EAAE,CAAC;YACZ,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAClC,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,25 @@
1
+ import { Net } from "../synth/Net";
2
+ import { Component } from "../synth/Component";
3
+ /** A snapshot of the circuit state needed for codegen. */
4
+ export interface CircuitSnapshot {
5
+ name: string;
6
+ components: Component<any>[];
7
+ nets: Net[];
8
+ placementAlgorithm?: import("../synth/types").PlacementAlgorithm;
9
+ }
10
+ /**
11
+ * Generate circuit-synth Python source code from a CircuitSnapshot.
12
+ *
13
+ * The output follows the pattern used in existing projects:
14
+ * ```python
15
+ * from circuit_synth import Component, Net, circuit
16
+ *
17
+ * @circuit(name="BoardName")
18
+ * def board_name():
19
+ * gnd = Net('GND', net_class="Power")
20
+ * r1 = Component(symbol="Device:R", ref="R1", ...)
21
+ * r1[1] += gnd
22
+ * return locals()
23
+ * ```
24
+ */
25
+ export declare function generatePython(snapshot: CircuitSnapshot): string;
@@ -0,0 +1,170 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generatePython = generatePython;
4
+ /**
5
+ * Collect all unique Nets referenced by the given components.
6
+ * Also includes any explicitly provided nets (e.g., floating nets).
7
+ */
8
+ function collectNets(components, extraNets = []) {
9
+ const seen = new Set();
10
+ for (const net of extraNets) {
11
+ seen.add(net);
12
+ }
13
+ for (const comp of components) {
14
+ for (const [, pin] of comp.allPins) {
15
+ if (pin.net) {
16
+ seen.add(pin.net);
17
+ }
18
+ }
19
+ }
20
+ return Array.from(seen);
21
+ }
22
+ /** Convert a ref like "R1" to a valid Python variable name "r1". */
23
+ function refToVar(ref) {
24
+ return ref.toLowerCase().replace(/[^a-z0-9_]/g, "_");
25
+ }
26
+ /** Convert a net name like "VCC_3V3" to a valid Python variable name. */
27
+ function netToVar(name) {
28
+ // Strip leading non-alphanumeric chars (e.g. "+5V" → "5V")
29
+ // then replace remaining special chars with underscores
30
+ let cleaned = name
31
+ .replace(/^[^a-zA-Z0-9]+/, "")
32
+ .replace(/[^a-zA-Z0-9_]/g, "_")
33
+ .toLowerCase();
34
+ // Python identifiers can't start with a digit, but we prefix with 'net_' anyway
35
+ return cleaned ? `net_${cleaned}` : "net_unnamed";
36
+ }
37
+ /** Escape a Python string value. */
38
+ function pyStr(s) {
39
+ return `"${s.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
40
+ }
41
+ /**
42
+ * Generate circuit-synth Python source code from a CircuitSnapshot.
43
+ *
44
+ * The output follows the pattern used in existing projects:
45
+ * ```python
46
+ * from circuit_synth import Component, Net, circuit
47
+ *
48
+ * @circuit(name="BoardName")
49
+ * def board_name():
50
+ * gnd = Net('GND', net_class="Power")
51
+ * r1 = Component(symbol="Device:R", ref="R1", ...)
52
+ * r1[1] += gnd
53
+ * return locals()
54
+ * ```
55
+ */
56
+ function generatePython(snapshot) {
57
+ const { name, components } = snapshot;
58
+ // Collect all nets (from component pins + explicit list)
59
+ const nets = collectNets(components, snapshot.nets);
60
+ const lines = [];
61
+ // ── Imports ──
62
+ lines.push(`from circuit_synth import Component, Net, circuit`);
63
+ lines.push(``);
64
+ // ── Function decorator + signature ──
65
+ const funcName = name.toLowerCase().replace(/[^a-z0-9_]/g, "_");
66
+ lines.push(`@circuit(name=${pyStr(name)})`);
67
+ lines.push(`def ${funcName}():`);
68
+ // ── Nets ──
69
+ if (nets.length > 0) {
70
+ lines.push(` # Nets`);
71
+ for (const net of nets) {
72
+ const varName = netToVar(net.name);
73
+ const classArg = net.class !== "Signal" ? `, net_class=${pyStr(net.class)}` : "";
74
+ lines.push(` ${varName} = Net(${pyStr(net.name)}${classArg})`);
75
+ }
76
+ lines.push(``);
77
+ }
78
+ // ── Components ──
79
+ if (components.length > 0) {
80
+ lines.push(` # Components`);
81
+ for (const comp of components) {
82
+ if (comp.symbol === "Device:DNC")
83
+ continue; // Skip marker components
84
+ const varName = refToVar(comp.ref);
85
+ const args = [];
86
+ args.push(`symbol=${pyStr(comp.symbol)}`);
87
+ args.push(`ref=${pyStr(comp.ref)}`);
88
+ args.push(`footprint=${pyStr(comp.footprint)}`);
89
+ if (comp.value) {
90
+ args.push(`value=${pyStr(comp.value)}`);
91
+ }
92
+ if (comp.description) {
93
+ args.push(`description=${pyStr(comp.description)}`);
94
+ }
95
+ if (comp.partNo) {
96
+ args.push(`LCSC_Number=${pyStr(comp.partNo)}`);
97
+ }
98
+ // ── Placement ──
99
+ const sPos = comp.absoluteSchematicPosition;
100
+ if (sPos.x !== 0 || sPos.y !== 0 || (sPos.rotation || 0) !== 0) {
101
+ args.push(`at=(${sPos.x}, ${sPos.y}, ${sPos.rotation || 0})`);
102
+ }
103
+ const pPos = comp.absolutePcbPosition;
104
+ if (pPos.x !== 0 || pPos.y !== 0 || (pPos.rotation || 0) !== 0 || pPos.side !== "front") {
105
+ args.push(`pcb_at=(${pPos.x}, ${pPos.y}, ${pPos.rotation || 0})`);
106
+ args.push(`pcb_side=${pyStr(pPos.side || "front")}`);
107
+ }
108
+ if (args.length <= 3) {
109
+ lines.push(` ${varName} = Component(${args.join(", ")})`);
110
+ }
111
+ else {
112
+ lines.push(` ${varName} = Component(`);
113
+ for (let i = 0; i < args.length; i++) {
114
+ const comma = i < args.length - 1 ? "," : "";
115
+ lines.push(` ${args[i]}${comma}`);
116
+ }
117
+ lines.push(` )`);
118
+ }
119
+ }
120
+ lines.push(``);
121
+ }
122
+ // ── Connections ──
123
+ const connectionLines = [];
124
+ for (const comp of components) {
125
+ if (comp.symbol === "Device:DNC")
126
+ continue; // Skip marker components
127
+ const compVar = refToVar(comp.ref);
128
+ for (const [pinKey, pin] of comp.allPins) {
129
+ const pinObj = pin;
130
+ if (!pinObj.net)
131
+ continue;
132
+ // Skip named aliases that point to the same pin as a numeric key.
133
+ const numericKey = parseInt(pinKey, 10);
134
+ if (isNaN(numericKey)) {
135
+ let hasNumericAlias = false;
136
+ for (const [otherKey, otherPin] of comp.allPins) {
137
+ if (otherKey !== pinKey && otherPin === pin && !isNaN(parseInt(otherKey, 10))) {
138
+ hasNumericAlias = true;
139
+ break;
140
+ }
141
+ }
142
+ if (hasNumericAlias)
143
+ continue;
144
+ }
145
+ const netVar = netToVar(pinObj.net.name);
146
+ // Check if this net contains a DNC component
147
+ const isDncNet = pinObj.net.pins.some(p => p.component.symbol === "Device:DNC");
148
+ if (isDncNet) {
149
+ // Find the DNC component to use its ref for the NC net name if possible,
150
+ // but circuit-synth pattern usually uses NC_<Ref>_<Pin>
151
+ const pinAccessor = !isNaN(numericKey) ? `[${numericKey}]` : `[${pyStr(pinKey)}]`;
152
+ connectionLines.push(` ${compVar}${pinAccessor} += Net(${pyStr(`NC_${comp.ref}_${pinKey}`)})`);
153
+ }
154
+ else {
155
+ const pinAccessor = !isNaN(numericKey) ? `[${numericKey}]` : `[${pyStr(pinKey)}]`;
156
+ connectionLines.push(` ${compVar}${pinAccessor} += ${netVar}`);
157
+ }
158
+ }
159
+ }
160
+ if (connectionLines.length > 0) {
161
+ lines.push(` # Connections`);
162
+ lines.push(...connectionLines);
163
+ lines.push(``);
164
+ }
165
+ // ── Return ──
166
+ lines.push(` return locals()`);
167
+ lines.push(``);
168
+ return lines.join("\n");
169
+ }
170
+ //# sourceMappingURL=codegen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codegen.js","sourceRoot":"","sources":["../../../src/cli/codegen.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * export: Export manufacturing files (Gerber, Drill, BOM, CPL) for JLCPCB.
3
+ *
4
+ * Generates:
5
+ * - Gerber files (all copper, paste, silkscreen, mask layers + edge cuts)
6
+ * - Drill files (Excellon format)
7
+ * - Drill map files (Gerber X2 format)
8
+ * - BOM CSV (JLCPCB format with LCSC Part #)
9
+ * - CPL CSV (JLCPCB pick & place format)
10
+ *
11
+ * All files are zipped into a single archive.
12
+ */
13
+ export declare function cmdExport(args: string[]): Promise<void>;