breadkit 0.1.0 → 0.2.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 (104) hide show
  1. checksums.yaml +4 -4
  2. data/.codespellignore +2 -0
  3. data/.yamllint +16 -0
  4. data/README.md +109 -6
  5. data/data/boards/double_full.yml +18 -0
  6. data/data/boards/stripboard.yml +9 -0
  7. data/data/boards/universal.yml +8 -0
  8. data/data/parts/2n3904.yml +11 -0
  9. data/data/parts/2n7000_onsemi_to92.yml +10 -0
  10. data/data/parts/74hc00.yml +22 -0
  11. data/data/parts/74hc04.yml +22 -0
  12. data/data/parts/74hc08.yml +22 -0
  13. data/data/parts/74hc14.yml +22 -0
  14. data/data/parts/74hc165.yml +24 -0
  15. data/data/parts/74hc32.yml +22 -0
  16. data/data/parts/74hc595.yml +24 -0
  17. data/data/parts/active_buzzer.yml +8 -0
  18. data/data/parts/ams1117_3v3.yml +12 -0
  19. data/data/parts/arduino_nano.yml +70 -0
  20. data/data/parts/arduino_uno.yml +29 -26
  21. data/data/parts/atmega328p.yml +37 -0
  22. data/data/parts/attiny85.yml +16 -0
  23. data/data/parts/battery_box.yml +8 -0
  24. data/data/parts/cd4017.yml +24 -0
  25. data/data/parts/ck_bd04.yml +29 -0
  26. data/data/parts/crystal.yml +7 -0
  27. data/data/parts/dc_jack_2wire.yml +8 -0
  28. data/data/parts/diode.yml +1 -0
  29. data/data/parts/esp32_devkitc_v4_wroom32e.yml +86 -0
  30. data/data/parts/irlz44n.yml +10 -0
  31. data/data/parts/l293d.yml +24 -0
  32. data/data/parts/led.yml +1 -0
  33. data/data/parts/lm358.yml +16 -0
  34. data/data/parts/lm393.yml +16 -0
  35. data/data/parts/ne555.yml +2 -2
  36. data/data/parts/ntc_thermistor.yml +7 -0
  37. data/data/parts/photoresistor.yml +8 -0
  38. data/data/parts/pico.yml +89 -0
  39. data/data/parts/resistor.yml +1 -0
  40. data/data/parts/sc56_11ewa.yml +30 -0
  41. data/data/parts/seeed_xiao_samd21.yml +37 -0
  42. data/data/parts/shillehtek_mb102_4pin.yml +23 -0
  43. data/data/parts/slide_switch_spst.yml +8 -0
  44. data/data/parts/sparkfun_pro_micro_5v.yml +58 -0
  45. data/data/parts/transistor.yml +0 -1
  46. data/data/parts/ua7805.yml +10 -0
  47. data/data/parts/uln2003a.yml +23 -0
  48. data/data/parts/wp154a4sureqbfzgc.yml +11 -0
  49. data/docs/CLI.md +108 -0
  50. data/docs/COMPATIBILITY.md +60 -0
  51. data/docs/DECLARATIVE.md +138 -0
  52. data/docs/IR.md +42 -0
  53. data/docs/JUMPER_KIT.md +45 -0
  54. data/docs/LOCK.md +75 -0
  55. data/docs/LSP.md +59 -0
  56. data/docs/MB102_POWER.md +11 -0
  57. data/docs/MCP.md +44 -0
  58. data/docs/RAKE.md +19 -0
  59. data/docs/dsl.md +197 -6
  60. data/exe/breadkit-lsp +13 -0
  61. data/exe/breadkit-mcp +12 -0
  62. data/lib/breadkit/analysis.rb +174 -50
  63. data/lib/breadkit/board.rb +152 -4
  64. data/lib/breadkit/cli.rb +229 -13
  65. data/lib/breadkit/color.rb +38 -0
  66. data/lib/breadkit/dc_analysis.rb +261 -0
  67. data/lib/breadkit/dsl.rb +205 -24
  68. data/lib/breadkit/exporters.rb +202 -0
  69. data/lib/breadkit/formatter.rb +52 -0
  70. data/lib/breadkit/fritzing_export.rb +256 -0
  71. data/lib/breadkit/ir.rb +154 -22
  72. data/lib/breadkit/jumper_kit.rb +127 -0
  73. data/lib/breadkit/lsp_server.rb +248 -0
  74. data/lib/breadkit/mcp_server.rb +133 -0
  75. data/lib/breadkit/model.rb +47 -5
  76. data/lib/breadkit/part_library.rb +156 -3
  77. data/lib/breadkit/part_lock.rb +107 -0
  78. data/lib/breadkit/patterns.rb +119 -0
  79. data/lib/breadkit/rake_task.rb +25 -0
  80. data/lib/breadkit/resolver.rb +160 -28
  81. data/lib/breadkit/structured_input.rb +275 -0
  82. data/lib/breadkit/templates/555.bk.rb +34 -0
  83. data/lib/breadkit/templates/arduino.bk.rb +17 -0
  84. data/lib/breadkit/templates/led.bk.rb +21 -0
  85. data/lib/breadkit/value.rb +42 -3
  86. data/lib/breadkit/version.rb +1 -1
  87. data/lib/breadkit/wire_suggestions.rb +106 -0
  88. data/lib/breadkit.rb +28 -3
  89. data/package.json +1 -1
  90. data/schema/board-v1.json +38 -0
  91. data/schema/ir-v1.json +56 -11
  92. data/schema/ir-v2.json +173 -0
  93. data/schema/part-v1.json +52 -4
  94. data/sig/breadkit.rbs +107 -5
  95. metadata +119 -14
  96. data/docs/assets/01_led_button.svg +0 -12
  97. data/site/assets/01_led_button.svg +0 -14
  98. data/site/assets/03_arduino_blink.svg +0 -14
  99. data/site/favicon.svg +0 -7
  100. data/site/guide/components/index.html +0 -113
  101. data/site/guide/dsl/index.html +0 -132
  102. data/site/guide/index.html +0 -163
  103. data/site/index.html +0 -95
  104. data/site/styles.css +0 -14
data/docs/CLI.md ADDED
@@ -0,0 +1,108 @@
1
+ # CLI reference
2
+
3
+ `breadkit` accepts Ruby circuit files (`.bk.rb`), declarative YAML
4
+ (`.bk.yml`, `.bk.yaml`) and TOML (`.bk.toml`) circuit files, and JSON IR files
5
+ where a circuit input is required. Ruby circuit files execute code; load only
6
+ files you trust. YAML and TOML circuit files are parsed as data. Ordinary `.yml`
7
+ part definitions are not circuit inputs.
8
+
9
+ | Command | Purpose |
10
+ | --- | --- |
11
+ | `breadkit new --template led\|555\|arduino [FILE]` | Create a runnable circuit file. The default name is `<template>.bk.rb`; an existing file is never overwritten. |
12
+ | `breadkit parts [FILE]` | List built-in parts and definitions loaded by `use_parts` in `FILE`. |
13
+ | `breadkit parts show PART [FILE]` | Print a part definition as JSON. |
14
+ | `breadkit check-part PART.yml` | Validate one YAML part definition. |
15
+ | `breadkit where HOLE FILE` | Show the hole's conductive strip, net, pins, and wire ends. |
16
+ | `breadkit explain REF FILE` | Show a component's pins, resolved nets, and constrained potentials. |
17
+ | `breadkit bom FILE` | Count parts by type and value, plus jumper wires. |
18
+ | `breadkit diff OLD NEW` | List changed board, supplies, labels, components, and wires. |
19
+ | `breadkit export --format FORMAT FILE` | Export `kicad`, `spice`, `wokwi`, `pins`, or `fritzing` data. |
20
+ | `breadkit fmt FILE` | Print a normalized declarative YAML or TOML circuit file. |
21
+ | `breadkit lock FILE` | Record the local part and board definition files used by a circuit in `breadkit.lock`. |
22
+ | `breadkit suggest FILE` | Print JSON candidates for unmet connection intent between placed pins. Each candidate names two free board holes; nothing is changed. |
23
+ | `breadkit kit --inventory KIT.yml FILE` | Allocate candidate jumpers from a measured YAML or JSON inventory. See [Jumper kits](JUMPER_KIT.md). |
24
+ | `breadkit patterns FILE` | Print recognized circuit patterns as JSON. An empty array means no supported pattern matched. |
25
+ | `breadkit console FILE` | Open IRB with the loaded `circuit` variable. |
26
+ | `breadkit doctor` | Check the Ruby version and availability of the optional linter and renderer commands. |
27
+
28
+ `nets`, `where`, and `explain` accept `--state SWITCH` for a closed switch state.
29
+ Their default is the all-open state. A regular switch uses its reference, such
30
+ as `SW1`. The C&K BD04 has four independent positions: `SW1.1` through
31
+ `SW1.4`. Separate selected positions with commas, for example
32
+ `breadkit nets --state SW1.1,SW1.4 circuit.bk.rb`. The position names are
33
+ Breadkit logical names, not a claim about the manufacturer's terminal numbers.
34
+ `explain` uses DC operating-point analysis for
35
+ voltage sources, resistors, LEDs, and diodes. It reports the fixed-drop diode
36
+ assumptions and labels ungrounded voltages as relative. Unsupported parts or
37
+ indeterminate circuits leave currents unknown. `bom` reports quantities, not
38
+ supplier part numbers or prices. `diff` compares resolved circuit content and
39
+ ignores source locations.
40
+
41
+ `nets`, `where`, `explain`, and `bom` print error diagnostics to standard error
42
+ and stop before printing inspection results when the circuit is invalid.
43
+ `suggest` follows the same rule. It skips state-specific expectations,
44
+ offboard or unplaced pins, occupied holes, holes under component bodies, and
45
+ connections that would merge nets with different known voltages.
46
+ An empty JSON list means no safe candidate was found; it does not prove the
47
+ intent is satisfied. Inspect each candidate before adding a `wire` declaration.
48
+
49
+ Use `breadkit ir --force FILE` to export a circuit with diagnostics. Supplies
50
+ can be marked `isolated: true`, and an inclusive voltage range such as
51
+ `3.0..4.2` can describe a battery whose voltage varies. Component values may
52
+ also include tolerance or ratings, such as `4.7k 5%`, `330 1/4W`, and
53
+ `10u 16V`.
54
+
55
+ ## Circuit patterns
56
+
57
+ `breadkit patterns FILE` identifies an unloaded two-resistor voltage divider
58
+ when exactly one fixed-voltage standalone supply and two resistors form a
59
+ series path between its terminals. It uses the DC analysis result for the
60
+ nominal midpoint voltage and reports that voltage relative to the supply's
61
+ negative terminal. The output names the top and bottom resistors and the
62
+ midpoint net:
63
+
64
+ ```sh
65
+ breadkit patterns divider.bk.rb
66
+ ```
67
+
68
+ The command also recognizes the exact, source-backed NE555 astable wiring used
69
+ by [the blinker example](../examples/02_555_blinker.bk.rb): a fixed supply
70
+ within the modeled NE555 range; RESET and VCC tied to supply positive; GND tied
71
+ to supply negative; TRIG and THR joined; a resistor from VCC to DIS; another
72
+ from DIS to TRIG/THR; a correctly polarized timing electrolytic to ground;
73
+ control and supply bypass capacitors; and an LED with its series resistor on
74
+ OUT. The pin relationships follow the [TI NE555 astable circuit](https://www.ti.com/lit/ds/symlink/ne555.pdf).
75
+ The result is labeled `ne555_astable_wiring`: it identifies a connection
76
+ pattern, not measured oscillation. No frequency or duty cycle is estimated.
77
+ Modified timing, reset, control, or output connections are not classified.
78
+
79
+ The command prints `[]` when a valid circuit matches neither supported
80
+ pattern. Invalid circuits report diagnostics and exit with an error. `[]` does
81
+ not mean the circuit is safe or has no useful topology.
82
+
83
+ ## Export formats
84
+
85
+ | Format | Supported output |
86
+ | --- | --- |
87
+ | `kicad` | [KiCad XML netlist](https://docs.kicad.org/9.0/en/eeschema/eeschema.html) with resolved component pin numbers and nets. It does not create a schematic or assign PCB footprints. |
88
+ | `spice` | [ngspice](https://ngspice.sourceforge.io/docs/ngspice-46-manual.pdf) operating-point netlist for fixed voltage supplies, resistors, and capacitors. Part references must begin with `R` or `C`. Other components and ranged supplies are rejected. |
89
+ | `wokwi` | [diagram.json](https://docs.wokwi.com/diagram-format) for Arduino Uno, resistors, and LEDs. Breadboard connections are flattened into wires between part pins. Standalone supplies and unsupported parts are rejected. Add a sketch to simulate it. |
90
+ | `pins` | Arduino C header constants for a connected Uno, or MicroPython constants for a connected Pico W / RP2040 board. Label nets to give constants stable signal names. |
91
+ | `fritzing` | Native, uncompressed Fritzing `.fz` sketch for the exact built-in 830-hole `full` breadboard, straight electrical jumpers, resistors, red 5 mm LEDs, and 4-pin tact switches. The 50-hole power rails must be unsplit. Resistor and LED leads must share a row; resistor pin 1 must be left of pin 2. Other parts, standalone supplies, net labels, boards, and styled wires are rejected with an error. |
92
+
93
+ Export stops when the circuit has error diagnostics. `kicad` preserves physical
94
+ pin numbers but leaves library and footprint assignment to the KiCad project.
95
+
96
+ For a supported full-board circuit, run `breadkit export --format fritzing
97
+ board.bk.rb > board.fz` and open `board.fz` in Fritzing. The exporter uses
98
+ Fritzing's bundled 830-hole breadboard, resistor, red LED, 4-pin pushbutton,
99
+ and wire parts. It does not generate a `.fzz` archive or import custom
100
+ Fritzing parts. The Fritzing export is available only for the documented
101
+ subset; use the renderer for a Breadkit diagram of other circuits. Resistor
102
+ values must be plain numbers with an optional engineering suffix (for example,
103
+ `330` or `1k`); values with a tolerance, power rating, or `Ω` suffix are
104
+ rejected because those properties are not yet preserved in this export.
105
+
106
+ See the [declarative circuit guide](DECLARATIVE.md) for complete YAML and TOML
107
+ examples. The same commands work with any supported circuit input format.
108
+ See [locking local definitions](LOCK.md) for the lockfile format and verification behavior.
@@ -0,0 +1,60 @@
1
+ # Compatibility and versioning
2
+
3
+ Breadkit, breadkit-lint, and breadkit-render are separate gems. Each gem has its
4
+ own version and release schedule. The lint and render gemspecs declare the core
5
+ versions they support; no shared release number is required.
6
+
7
+ Breadkit is currently a 0.x project. Until 1.0, a minor release may change the
8
+ Ruby DSL, CLI, or analysis behavior. Patch releases preserve their documented
9
+ inputs and output contracts. After 1.0, incompatible DSL or Ruby API changes
10
+ require a new major gem version.
11
+
12
+ JSON interfaces have their own `schema_version`, independent of gem versions:
13
+
14
+ | Interface | Current schema | Compatibility rule |
15
+ | --- | --- | --- |
16
+ | Circuit IR | [v1](https://breadkit.github.io/breadkit/schema/ir-v1.json) for one unnamed board; [v2](https://breadkit.github.io/breadkit/schema/ir-v2.json) for named boards | A reader accepts supported versions explicitly. A breaking field or meaning change requires a new schema version. |
17
+ | Part YAML | [v1](https://breadkit.github.io/breadkit/schema/part-v1.json) | New optional fields may be added. Existing fields keep their meaning within v1. |
18
+ | Board YAML | [v1](https://breadkit.github.io/breadkit/schema/board-v1.json) | New optional fields may be added. Existing fields keep their meaning within v1. |
19
+
20
+ The JSON IR writer selects v1 for a single unnamed board and v2 for named
21
+ boards. Consumers should check `schema_version` before reading an IR file and
22
+ ignore unknown optional fields. They should not infer the IR version from the
23
+ gem version. The linter publishes its own [result schema](https://breadkit.github.io/breadkit-lint/schemas/lint-v1.json).
24
+
25
+ ## Editor schema associations
26
+
27
+ Part and board files can use any YAML filename when referenced by `use_parts`
28
+ or `use_boards`. The optional `.bkpart.yml` and `.bkboard.yml` endings make
29
+ editor associations unambiguous. In VS Code with the YAML extension, use a
30
+ modeline at the start of an individual file:
31
+
32
+ ```yaml
33
+ # yaml-language-server: $schema=https://breadkit.github.io/breadkit/schema/part-v1.json
34
+ id: custom_part
35
+ pins:
36
+ - {num: 1, name: SIGNAL}
37
+ ```
38
+
39
+ For a whole workspace, add this to `.vscode/settings.json`:
40
+
41
+ ```json
42
+ {
43
+ "yaml.schemas": {
44
+ "https://breadkit.github.io/breadkit/schema/part-v1.json": "*.bkpart.yml",
45
+ "https://breadkit.github.io/breadkit/schema/board-v1.json": "*.bkboard.yml"
46
+ },
47
+ "json.schemas": [
48
+ { "fileMatch": ["*.bkir.json"], "url": "https://breadkit.github.io/breadkit/schema/ir-v1.json" },
49
+ { "fileMatch": ["*.bkir-v2.json"], "url": "https://breadkit.github.io/breadkit/schema/ir-v2.json" }
50
+ ]
51
+ }
52
+ ```
53
+
54
+ Use `ir-v2.json` for named-board IR. `.bkir.json` and `.bkir-v2.json` are
55
+ optional filenames; `Breadkit.load` accepts any `.json` circuit IR file.
56
+
57
+ Before a 1.0 release, changes to a public schema or documented DSL form need
58
+ round-trip coverage and an entry in the relevant gem's changelog. The published
59
+ schema files are versioned artifacts; changing a v1 schema to reinterpret
60
+ existing fields is a breaking change and requires v2 instead.
@@ -0,0 +1,138 @@
1
+ # YAML and TOML circuit files
2
+
3
+ Use `.bk.yml` or `.bk.yaml` for YAML and `.bk.toml` for TOML. Breadkit parses
4
+ these files as data and passes their declarations through the same builder and
5
+ resolver used by the Ruby DSL. Ordinary `.yml` files remain part definitions.
6
+
7
+ Try the complete [YAML](../examples/06_declarative_led.bk.yml) and
8
+ [TOML](../examples/07_declarative_led.bk.toml) LED examples:
9
+
10
+ ```sh
11
+ breadkit nets examples/06_declarative_led.bk.yml
12
+ breadkit ir examples/07_declarative_led.bk.toml > circuit.json
13
+ breadkit fmt examples/06_declarative_led.bk.yml > formatted.bk.yml
14
+ ```
15
+
16
+ The YAML example describes a USB supply, resistor, LED, jumper wire, and three
17
+ expected connections:
18
+
19
+ ```yaml
20
+ title: LED circuit
21
+ board: mini
22
+ supplies:
23
+ - {name: USB, voltage: 5, plus: a1, minus: a2}
24
+ labels:
25
+ - {name: VCC, at: a1}
26
+ - {name: GND, at: a2}
27
+ parts:
28
+ - {ref: R1, type: resistor, value: "330", pins: [b1, b3]}
29
+ - {ref: D1, type: led, pins: {anode: c3, cathode: c4}, attrs: {color: red}}
30
+ wires:
31
+ - {from: d4, to: b2, color: black}
32
+ expectations:
33
+ - connected: [[VCC, R1.1], [R1.2, D1.anode], [D1.cathode, GND]]
34
+ ```
35
+
36
+ ## Fields
37
+
38
+ | Field | Shape | Meaning |
39
+ | --- | --- | --- |
40
+ | `title` | text | Circuit title. |
41
+ | `board` | text or mapping | Board type, optionally `{type: full, split_rails: true}`. |
42
+ | `boards` | list of mappings | Named boards with `name`, `type`, and optional `split_rails`; use instead of `board`. Qualify holes as `B1.a1`. |
43
+ | `use_parts`, `use_boards` | path or list of paths | Load definitions relative to the circuit file. Globs are accepted. |
44
+ | `supplies` | list of mappings | Either `name`, `voltage`, `plus`, `minus` for a standalone source, or `from`, `plus`, `minus` to route a defined offboard output. Standalone sources also accept `isolated` and numeric `current_limit`. |
45
+ | `labels` | list of mappings | `name` and `at` for a named net. |
46
+ | `parts` | list of mappings | `ref`, `type`; optional `value`, `pins`, `at`, `attrs`, `unused`. |
47
+ | `offboard` | list of mappings | `ref`, `type`; optional `side`, `at`, `attrs`, `unused`. `offboard: true` also works in a `parts` entry. |
48
+ | `wires` | list of mappings | `from`, `to`; optional `color`, `id`, `route`, `layer`, `electrical`, `dashed`. |
49
+ | `connections` | list of mappings | Intent assertions with `from`, `to`, and optional `when` switch state. They do not place wires. |
50
+ | `expectations` | list of mappings | Optional `strict`, `when`, and connection, isolation, net, voltage, or current checks. |
51
+ | `lint_disables` | list of mappings | `rule`; optional `on` and `reason`. |
52
+
53
+ Quote `"on"` when using that key in YAML, because YAML parsers may interpret
54
+ an unquoted `on` as a boolean.
55
+
56
+ Use a list for positional part pins (`pins: [b1, b3]`) or a mapping for named
57
+ pins (`pins: {anode: c3, cathode: c4}`). `attrs` holds part-specific options,
58
+ such as `color`, `rotate`, or `mirror`. Supply voltage can be a number, a value
59
+ string such as `3.3V`, or an inclusive range string such as `3.0..4.2`. Part
60
+ values accept the same notation as the Ruby DSL, including `4.7k 5%`,
61
+ `330 1/4W`, and `10u 16V`.
62
+
63
+ Declare expected connectivity separately from physical wiring:
64
+
65
+ ```yaml
66
+ connections:
67
+ - {from: R1.1, to: D1.anode}
68
+ wires:
69
+ - {from: b1, to: a5}
70
+ ```
71
+
72
+ The connection records the same IR expectation as Ruby `connect`; only the
73
+ wire changes connectivity. Run `bklint` to report a mismatch or an unknown
74
+ reference. Run `breadkit suggest FILE` for free-hole candidates when both pins
75
+ are physically placed. TOML uses `[[connections]]` with `from` and `to` fields.
76
+
77
+ An expectation can contain `connected` or `isolated` as lists of reference
78
+ lists, `nets` as a list of `{name, refs}` mappings, and `voltage` or `current`
79
+ as lists of `{ref, range}` mappings. Measurement ranges use inclusive strings
80
+ such as `"3.0..3.6"`. `when` names a switch state. Example:
81
+
82
+ ```yaml
83
+ expectations:
84
+ - strict: true
85
+ connected: [[VCC, R1.1]]
86
+ isolated: [[VCC, GND]]
87
+ nets: [{name: VCC, refs: [R1.1]}]
88
+ voltage: [{ref: VCC, range: "4.8..5.2"}]
89
+ ```
90
+
91
+ For TOML, use a `[[section]]` array of tables for each list entry. The
92
+ [complete TOML example](../examples/07_declarative_led.bk.toml) shows this
93
+ structure. For a custom offboard module, define its part in YAML and load it
94
+ with `use_parts`:
95
+
96
+ ```yaml
97
+ board: mini
98
+ use_parts: [sensor.yml]
99
+ offboard:
100
+ - {ref: SENSOR, type: sensor, side: left}
101
+ wires:
102
+ - {from: SENSOR.SIG, to: a1}
103
+ ```
104
+
105
+ YAML object tags and aliases are rejected. Unknown fields and invalid field
106
+ types produce input errors. Diagnostics from declarative files currently point
107
+ to the file's first line rather than the individual field.
108
+
109
+ For multiple boards, use `boards` instead of `board`:
110
+
111
+ ```yaml
112
+ boards:
113
+ - {name: B1, type: half}
114
+ - {name: B2, type: mini}
115
+ wires:
116
+ - {from: B1.a1, to: B2.j1}
117
+ ```
118
+
119
+ This produces version 2 IR. See the [DSL reference](dsl.md#multiple-boards)
120
+ for board identity and connection rules.
121
+
122
+ An offboard output can feed rails without declaring a duplicate voltage source:
123
+
124
+ ```yaml
125
+ board: half
126
+ offboard:
127
+ - {ref: UNO, type: arduino_uno}
128
+ supplies:
129
+ - {from: UNO.5V, plus: T+, minus: T-}
130
+ ```
131
+
132
+ The output voltage and return pin come from the part's `provides` definition.
133
+ Both rail destinations are required, and the resolved IR contains two wires.
134
+
135
+ `breadkit fmt FILE` prints canonical YAML or TOML without modifying the input.
136
+ It validates the circuit fields first and keeps the original format. Formatting
137
+ discards comments, so review the output before replacing a commented source
138
+ file. Ruby DSL files are not supported by this formatter.
data/docs/IR.md ADDED
@@ -0,0 +1,42 @@
1
+ # JSON circuit IR
2
+
3
+ Breadkit IR is a resolved circuit in JSON. Generate it from a circuit file to
4
+ pass the same circuit to Breadkit, breadkit-render, breadkit-lint, or another
5
+ tool. JSON input is data-only; Ruby DSL input executes code.
6
+
7
+ ```sh
8
+ breadkit ir examples/06_declarative_led.bk.yml > circuit.json
9
+ breadkit nets circuit.json
10
+ ```
11
+
12
+ Here is a compact, valid v1 IR input for a circuit using built-in definitions:
13
+
14
+ ```json
15
+ {
16
+ "schema_version": 1,
17
+ "title": "LED circuit",
18
+ "board": { "type": "mini", "options": { "split_rails": false } },
19
+ "supplies": [
20
+ { "name": "USB", "voltage": 5, "plus": "a1", "minus": "a2", "source": null }
21
+ ],
22
+ "labels": [],
23
+ "components": [
24
+ { "ref": "R1", "part": "resistor", "value": "330", "attrs": {},
25
+ "pins": { "1": "b1", "2": "b3" }, "unused": [], "source": null },
26
+ { "ref": "D1", "part": "led", "value": null, "attrs": { "color": "red" },
27
+ "pins": { "anode": "c3", "cathode": "c4" }, "unused": [], "source": null }
28
+ ],
29
+ "wires": [
30
+ { "id": "W1", "from": "d4", "to": "b2", "color": null,
31
+ "route": "straight", "source": null }
32
+ ],
33
+ "expectations": []
34
+ }
35
+ ```
36
+
37
+ `breadkit ir` writes additional resolved details, including the board
38
+ definition, any custom part definitions, source locations, and `analysis.nets`.
39
+ The reader recalculates `analysis` when loading IR. Use
40
+ [IR v1](../schema/ir-v1.json) for one unnamed board and
41
+ [IR v2](../schema/ir-v2.json) for named boards. See the
42
+ [compatibility policy](COMPATIBILITY.md) before consuming IR in another tool.
@@ -0,0 +1,45 @@
1
+ # Jumper kit allocation
2
+
3
+ Record the usable span of the jumpers you own, measured between the hole
4
+ centers they can reach after insertion. Use millimeters and count each color
5
+ and size separately:
6
+
7
+ ```yaml
8
+ wires:
9
+ - {color: red, usable_span_mm: 12, count: 4}
10
+ - {color: black, usable_span_mm: 20, count: 3}
11
+ measured_routes:
12
+ W3: 18
13
+ ```
14
+
15
+ Run `breadkit kit --inventory kit.yml circuit.bk.yml`. JSON inventories with
16
+ the same structure are accepted. The command prints JSON with `assignments`,
17
+ `unassigned`, and `skipped` arrays. Each assignment includes a wire ID, color,
18
+ chosen usable span, required span, and its source (`board_geometry` or
19
+ `measured`). For a measured route without board geometry, `minimum_span_mm` is
20
+ null. Inventory counts
21
+ are never reused. A wire with an explicit color only matches the same color;
22
+ an uncolored wire can use any inventory color. Color names are compared without
23
+ case. The command leaves the circuit and inventory unchanged.
24
+
25
+ The allocator uses the 2.54 mm terminal-hole geometry of the packaged mini,
26
+ half, full, and double-full breadboards. Without a `measured_routes` entry, it
27
+ considers only electrical, straight wires between terminal holes on the same
28
+ board. It skips rail and offboard endpoints, solder boards, custom boards
29
+ without verified pitch, cross-board wires, and curved or edge routes with a
30
+ reason in `skipped`. Board spacing in a multi-board diagram is for display and
31
+ cannot determine a real cable length.
32
+
33
+ Use `measured_routes` when you have measured the required usable cable span for
34
+ a specific wire, including bends, rise, and the chosen physical route. This
35
+ allows a rail, offboard, curved, or cross-board wire to use the kit without
36
+ pretending its diagram coordinates are physical measurements. Wire IDs must
37
+ exist in the circuit; give such wires explicit `id:` values if declarations
38
+ may be reordered. A measured span for a terminal wire cannot be shorter than
39
+ the modeled endpoint span. Visual-only wires cannot receive a measured route.
40
+
41
+ The modeled endpoint span is a lower bound. Routing around components, wire rise,
42
+ connector shape, and how the board is mounted can require more length. Measure
43
+ `usable_span_mm` with those allowances and inspect each proposed assignment
44
+ before building. An `unassigned` entry means the inventory cannot cover an
45
+ eligible wire under these constraints; it does not change the circuit.
data/docs/LOCK.md ADDED
@@ -0,0 +1,75 @@
1
+ # Locking local definitions
2
+
3
+ Circuit files can load local YAML part and board definitions with `use_parts`
4
+ and `use_boards`. Patterns may match different files after a project changes.
5
+ Run `breadkit lock FILE` to record the exact matched paths and their SHA-256
6
+ checksums:
7
+
8
+ ```yaml
9
+ # logger.bk.yml
10
+ board: mini
11
+ use_parts: [parts/*.yml]
12
+ offboard:
13
+ - {ref: SENSOR, type: custom_sensor}
14
+ ```
15
+
16
+ ```sh
17
+ breadkit lock logger.bk.yml
18
+ breadkit nets logger.bk.yml
19
+ ```
20
+
21
+ The command writes `breadkit.lock` beside the circuit. Commit the lockfile
22
+ with the circuit and definitions. Each entry records a circuit filename, the
23
+ Breadkit version, and relative paths and checksums for its local part and
24
+ board YAML files. Multiple circuit files in one directory have separate
25
+ entries in the same lockfile. Running `breadkit lock FILE` again updates only
26
+ that circuit's entry.
27
+
28
+ When a lockfile exists, Breadkit checks the entry before resolving a Ruby,
29
+ YAML, or TOML circuit. A changed definition, a new or removed glob match, a
30
+ different Breadkit version, or a missing circuit entry stops loading with an
31
+ error. Run `breadkit lock FILE` again after intentionally changing local
32
+ definitions. This check also applies to the MCP and LSP servers when they
33
+ resolve supported circuit inputs. JSON IR files are self-contained and do not
34
+ use the lockfile.
35
+
36
+ The lockfile pins only local YAML definitions loaded by `use_parts` and
37
+ `use_boards`, plus the Breadkit version. It does not hash the circuit source,
38
+ Ruby DSL files loaded with `include`, other gems, or external tools. Ruby DSL
39
+ files are executable and should only be loaded when trusted. Declarative YAML
40
+ and TOML circuit files remain data-only.
41
+
42
+ ## Vendored part packs
43
+
44
+ To share a versioned pack today, keep its YAML files under your project, for
45
+ example as a Git submodule pinned to a commit under `vendor/parts/`. Point
46
+ `use_parts` at those local files and commit both the Git revision and
47
+ `breadkit.lock`. The lock checks the exact YAML bytes even if a submodule or
48
+ checkout changes unexpectedly:
49
+
50
+ ```yaml
51
+ board: mini
52
+ use_parts: [vendor/parts/*.yml]
53
+ ```
54
+
55
+ Breadkit does not download packs, resolve remote versions, or authenticate a
56
+ Git source. Those steps remain with your existing Git or package manager
57
+ workflow. Avoid loading unpinned remote files directly into a circuit.
58
+
59
+ For a shared Git pack, pin the submodule to a reviewed commit and commit the
60
+ submodule pointer, circuit, and generated lockfile together. In CI, check out
61
+ submodules before running Breadkit. A pack repository can validate each
62
+ definition with `breadkit check-part`; editors can use the public
63
+ [`part-v1` schema](https://breadkit.github.io/breadkit/schema/part-v1.json):
64
+
65
+ ```sh
66
+ for file in parts/*.yml; do
67
+ breadkit check-part "$file"
68
+ done
69
+ ```
70
+
71
+ Consumers should run `breadkit nets FILE` or `breadkit ir FILE` in CI after
72
+ the submodule checkout. That verifies the recorded SHA-256 bytes and the
73
+ exact set of matched definitions before a diagram or report is produced.
74
+ The Git commit pins the pack version; `breadkit.lock` catches changed YAML
75
+ bytes or newly matched files even when the checkout differs from that commit.
data/docs/LSP.md ADDED
@@ -0,0 +1,59 @@
1
+ # Language server and VS Code extension
2
+
3
+ `breadkit-lsp` is a stdio Language Server Protocol 3.18 server. It provides:
4
+
5
+ - Full-document diagnostics as a YAML or TOML circuit is edited.
6
+ - Completion for board holes, rail holes, component pins, and net labels.
7
+ - Hover with the resolved net name and potential. Unconstrained potentials are
8
+ shown as unknown.
9
+
10
+ The server accepts `.bk.yml`, `.bk.yaml`, `.bk.toml`, and `.bk.rb` documents.
11
+ YAML and TOML buffers use safe data parsers and do not execute Ruby. Ruby DSL
12
+ files receive hole completion without evaluation by default. To enable full
13
+ Ruby diagnostics, component pin completion, and net hover, start the server
14
+ with both `--root DIRECTORY` and `--trusted-ruby`. This evaluates Ruby source,
15
+ including unsaved edits, with the permissions of the server process. Use it
16
+ only for code you trust. `--root` limits data-only circuit files and declared
17
+ part or board files to that directory. It is not a sandbox for Ruby code.
18
+
19
+ ```sh
20
+ breadkit-lsp --root /path/to/project
21
+ ```
22
+
23
+ The server uses standard LSP framing on stdin/stdout. It supports `initialize`,
24
+ `shutdown`, `exit`, full `didOpen`/`didChange`/`didClose` synchronization,
25
+ `textDocument/completion`, `textDocument/hover`, and push diagnostics. Run it
26
+ from an LSP client; stdout is reserved for protocol messages.
27
+
28
+ ## VS Code
29
+
30
+ The source for the minimal desktop extension is in [`vscode/`](../vscode/).
31
+ It needs VS Code 1.100 or newer and the `breadkit` gem installed in the Ruby
32
+ environment used by VS Code. Preview also needs the separately installed
33
+ `breadkit-render` gem (`bkrender` command).
34
+
35
+ To make a local VSIX with the [VS Code extension packaging tool](https://code.visualstudio.com/api/working-with-extensions/publishing-extension):
36
+
37
+ ```sh
38
+ cd vscode
39
+ npx --yes @vscode/vsce@4.0.0 package --no-dependencies
40
+ code --install-extension breadkit-0.1.0.vsix
41
+ ```
42
+
43
+ Open a `.bk.yml`, `.bk.yaml`, `.bk.toml`, or `.bk.rb` file. The extension starts
44
+ the server when a Breadkit file is opened. Run **Breadkit: Preview Circuit**
45
+ from the Command Palette to render the saved file as a static, dark SVG in a
46
+ side panel. Save edits before previewing. Preview runs only in a trusted
47
+ workspace. For Ruby files, set `breadkit.evaluateRubyDsl` to `true` as well.
48
+ The setting also enables Ruby analysis after the extension host restarts.
49
+
50
+ Set `breadkit.serverCommand` or `breadkit.renderCommand` if the commands are
51
+ not on VS Code's `PATH`. The extension uses direct process execution without
52
+ a shell. With one workspace folder, it passes that folder as `--root`. In a
53
+ multi-folder window, data-only files work but Ruby evaluation remains disabled.
54
+
55
+ Diagnostics from declarative files currently point to the first line of the
56
+ file because the shared data loader does not preserve field locations.
57
+ Completion is prefix-based; source with a parse error may have fewer
58
+ suggestions. Hover reports resolved supply potential only and does not imply
59
+ current or a simulated operating point.
@@ -0,0 +1,11 @@
1
+ # ShillehTek MB102 four-pin power module
2
+
3
+ `shillehtek_mb102_4pin` models the [ShillehTek MB102 3.3 V/5 V module](https://shillehtek.com/blogs/shillehtek-product-manuals/mb102-breadboard-power-supply-3-3v-5v) described as having four underside contacts and independent left and right 5 V / OFF / 3.3 V jumpers. It also models the master power switch. This is a named variant, not a pinout for every board sold as “MB102.” For example, the [Rajguru MB102 circuit diagram](https://www.rajguruelectronics.com/Product/1240/111225145243.pdf) depicts four two-contact connectors (J2–J5) on a different revision.
4
+
5
+ The four contacts are logical names: `LEFT_POS`, `LEFT_GND`, `RIGHT_POS`, and `RIGHT_GND`. The catalog assigns no contact numbers, mounting row offsets, or fixed footprint. Match each contact on **your** module to its rail hole and enter all four hole IDs. The resolver rejects missing pins, duplicate holes, terminal-strip holes, and holes on a rail of the wrong polarity. It cannot confirm that the chosen holes match the physical spacing of a particular module; check the fit before powering it.
6
+
7
+ The [source template](../examples/templates/shillehtek_mb102_4pin.bk.rb) reads four verified hole IDs from environment variables. For a board you have measured, set `MB102_LEFT_POS`, `MB102_LEFT_GND`, `MB102_RIGHT_POS`, and `MB102_RIGHT_GND`, then run `breadkit nets examples/templates/shillehtek_mb102_4pin.bk.rb`. The template selects 3.3 V on the left and 5 V on the right; change `left:` and `right:` to `:v5`, `:v3_3`, or `:off` to match the physical jumpers. Set `master: :off` when the switch is off. All three settings are required so an omitted jumper position cannot silently energize a rail.
8
+
9
+ With `master: :on`, each selected side contributes its own voltage source between that side's positive and ground contacts. `:off` contributes no source to that positive rail. The ground contacts remain connected internally, including when either output or the master switch is off. If the breadboard has split rails, bridge each intended segment explicitly; the module energizes only the segment that holds its contact.
10
+
11
+ The built-in drawing is a logical marker, not a to-scale body or a claim that the module fits over any four chosen holes. The ShillehTek manual lists 6.5–12 V for the center-positive barrel input and 5 V for USB input, with a claimed maximum of 700 mA per rail. The circuit model assumes the selected output voltage is available; it does not simulate regulator dropout, heat, USB supply limits, or simultaneous input selection. Verify the power source and load against the actual board and adapter before assembly.
data/docs/MCP.md ADDED
@@ -0,0 +1,44 @@
1
+ # MCP server
2
+
3
+ `breadkit-mcp` exposes read-only circuit inspection over the Model Context
4
+ Protocol (MCP) stdio transport. It uses the [official Ruby MCP SDK](https://ruby.sdk.modelcontextprotocol.io/server/transports/).
5
+
6
+ Start the server from a project directory:
7
+
8
+ ```sh
9
+ breadkit-mcp
10
+ ```
11
+
12
+ The current directory is the file root. Set it explicitly when your MCP client
13
+ starts the server elsewhere:
14
+
15
+ ```sh
16
+ breadkit-mcp --root /absolute/path/to/project
17
+ ```
18
+
19
+ A client configuration that accepts `command` and `args` can use:
20
+
21
+ ```json
22
+ {
23
+ "command": "breadkit-mcp",
24
+ "args": ["--root", "/absolute/path/to/project"]
25
+ }
26
+ ```
27
+
28
+ The server offers three tools:
29
+
30
+ | Tool | Input | Result |
31
+ | --- | --- | --- |
32
+ | `breadkit_resolve` | `path` | Board and component summary, validity, and diagnostics. |
33
+ | `breadkit_nets` | `path`, optional `state` | Electrical nets, members, holes, and constrained potentials. Use `state: "base"` for the default switch state. |
34
+ | `breadkit_ir` | `path` | The resolved JSON IR. Requires a circuit without error diagnostics. |
35
+
36
+ All project paths must remain inside the configured root, including symlink
37
+ targets and referenced part or board definition files. Accepted circuit inputs are
38
+ `.bk.yml`, `.bk.yaml`, `.bk.toml`, and `.json` IR. Ruby DSL files are not
39
+ evaluated by this server. Tool failures return MCP `isError` results, and
40
+ standard output contains only protocol messages.
41
+
42
+ See the [MCP tools specification](https://modelcontextprotocol.io/specification/2025-11-25/server/tools)
43
+ for the tool protocol and the [stdio transport specification](https://modelcontextprotocol.io/specification/2026-07-28/basic/transports/stdio)
44
+ for message framing.
data/docs/RAKE.md ADDED
@@ -0,0 +1,19 @@
1
+ # Check circuits with Rake
2
+
3
+ Install Rake for your project and add an opt-in task to its `Rakefile`:
4
+
5
+ ```ruby
6
+ require "breadkit/rake_task"
7
+
8
+ Breadkit::RakeTask.new(:circuits, files: Dir["circuits/*.{bk.yml,bk.toml}"])
9
+ task default: :circuits
10
+ ```
11
+
12
+ Run `bundle exec rake circuits`. The task loads each listed file, verifies
13
+ `breadkit.lock` when present, and fails on core resolution errors. It reports
14
+ the first failing file and its diagnostics. The task does not run lint rules;
15
+ run `bklint` separately when you need electrical and layout checks.
16
+
17
+ Only files passed in `files:` are loaded. Ruby `.bk.rb` circuits execute Ruby
18
+ code, so include them only when you trust their contents. YAML and TOML
19
+ circuit files are parsed as data.