Metadata-Version: 2.4
Name: perfboard-studio
Version: 0.11.0
Summary: Perfboard layout designer: netlist-driven placement and routing, perfboard-specific design rules, layout-vs-schematic verification, and a step-by-step soldering guide with measurement checkpoints.
License-Expression: Apache-2.0
Project-URL: Homepage, https://github.com/medinstech/perfboard-studio
Project-URL: Repository, https://github.com/medinstech/perfboard-studio
Project-URL: Documentation, https://github.com/medinstech/perfboard-studio#where-everything-else-is-written-down
Project-URL: Changelog, https://github.com/medinstech/perfboard-studio/blob/main/CHANGELOG.md
Project-URL: Issues, https://github.com/medinstech/perfboard-studio/issues
Keywords: perfboard,stripboard,veroboard,protoboard,eda,pcb,kicad,netlist,autorouter,drc,lvs,electronics,soldering
Classifier: Development Status :: 2 - Pre-Alpha
Classifier: Environment :: X11 Applications :: Qt
Classifier: Intended Audience :: Manufacturing
Classifier: Intended Audience :: Science/Research
Classifier: Natural Language :: English
Classifier: Natural Language :: Turkish
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: NOTICE
Requires-Dist: PySide6>=6.10
Requires-Dist: vtk>=9.6
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == "dev"
Requires-Dist: pytest-cov; extra == "dev"
Requires-Dist: mypy>=1.13; extra == "dev"
Requires-Dist: ruff>=0.8; extra == "dev"
Requires-Dist: pyinstaller>=6.10; extra == "dev"
Requires-Dist: trove-classifiers; extra == "dev"
Provides-Extra: mcp
Requires-Dist: mcp<2,>=1.0; extra == "mcp"
Dynamic: license-file

<p align="center">
  <a href="https://medinstech.com">
    <picture>
      <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/medinstech/perfboard-studio/main/docs/images/wordmark-white.png">
      <img alt="Medinstech" src="https://raw.githubusercontent.com/medinstech/perfboard-studio/main/docs/images/wordmark-blue.png" height="96">
    </picture>
  </a>
</p>

<h1 align="center">Perfboard Studio</h1>

<p align="center"><b>Perfboard circuit design and soldering guides</b></p>

<p align="center">
  A desktop app that takes a schematic netlist, lays it out on pad-per-hole<br>
  perfboard, lets the router work out the connections, proves the board matches<br>
  the schematic, and writes a step-by-step build guide with measurement<br>
  checkpoints.
</p>

<p align="center">
  <a href="https://github.com/medinstech/perfboard-studio/actions/workflows/ci.yml"><img alt="tests" src="https://img.shields.io/github/actions/workflow/status/medinstech/perfboard-studio/ci.yml?branch=main&style=flat-square&label=tests"></a>
  <a href="https://github.com/medinstech/perfboard-studio/releases/latest"><img alt="latest release" src="https://img.shields.io/github/v/release/medinstech/perfboard-studio?style=flat-square&color=0d00ff&label=release"></a>
  <a href="https://github.com/medinstech/perfboard-studio/blob/main/pyproject.toml"><img alt="Python 3.12+" src="https://img.shields.io/badge/python-3.12%2B-0d00ff?style=flat-square"></a>
  <a href="https://github.com/medinstech/perfboard-studio/blob/main/LICENSE"><img alt="Apache-2.0" src="https://img.shields.io/badge/license-Apache--2.0-0d00ff?style=flat-square"></a>
</p>

<p align="center">
  <a href="https://github.com/medinstech/perfboard-studio/releases/latest"><b>Download</b></a>
  &nbsp;·&nbsp; <a href="#running-it"><b>uv tool install perfboard-studio</b></a>
  &nbsp;·&nbsp; <a href="https://github.com/medinstech/perfboard-studio/blob/main/docs/MCP.md">MCP server</a>
  &nbsp;·&nbsp; <a href="#or-open-one-that-is-already-built">Example boards</a>
  &nbsp;·&nbsp; <a href="https://github.com/medinstech/perfboard-studio/blob/main/CHANGELOG.md">Changelog</a>
  &nbsp;·&nbsp; <a href="https://github.com/medinstech/perfboard-studio/blob/main/README.tr.md">Türkçe</a>
</p>

![the 2D editor, with an NE555 astable placed and routed](https://raw.githubusercontent.com/medinstech/perfboard-studio/main/docs/images/editor-component-side.png)

<p align="center">
  The status bar is the whole claim: fourteen connections across seven nets,<br>
  three of which needed a wire, DRC clean and LVS agreeing with the schematic.
</p>

---

- **A soldering guide with verification steps.** Not just "solder R1 here", but
  *"block 2 complete → U1 pin 4 to C3(−) must show continuity"* and *"before
  power-on: GND to V+ must read above 10 kΩ"*. Derived from the netlist, so it is
  exact rather than generic advice.
- **Perfboard LVS.** The board's real connectivity is extracted and compared
  against the schematic. Opens, shorts and floating conductors are reported
  before you pick up the iron.
- **Six kinds of connection, not one.** A lead bend, a solder trace, a wired
  solder trace, bare wire, insulated wire and a top jumper have different costs,
  limits and failure modes, and the router prices all six — which is what makes
  a layout that is pleasant to actually solder.
- **Three rules only the third dimension can see.** A part too tall for the case,
  a jumper trapped under a body that gets soldered down on top of it, and a
  heat-sensitive part sitting too close to a hot one. The 3D view is a checking
  tool, not a picture.
- **The sheet is derived, never stored.** No symbol positions live in the file,
  so there is no second copy of the circuit to keep in step with the netlist and
  nothing to lay out by hand.
- **Agent-native.** An MCP server, a headless CLI and a git-diffable project
  file, all driving the same command bus as the GUI — so undo works across a
  session where a human and a model both edit the board.

> **Status: pre-alpha, and end to end.** A netlist goes in and a soldering guide
> comes out. What is missing is the dogfood test — nobody has yet built a real
> board by following a generated guide, and [PLAN.md](https://github.com/medinstech/perfboard-studio/blob/main/PLAN.md) §11
> says M5 does not close until somebody has. Everything else runs: **v0.10.0**
> ships an installer for each of the three desktop platforms, none code-signed.

**Jump to** — [Running it](#running-it) ·
[Connections](#connections-are-not-all-the-same-thing) ·
[Both faces](#both-faces-and-the-third-dimension) ·
[The schematic](#draw-the-circuit-first) ·
[The guide](#the-guide-has-an-order-and-you-can-watch-it) ·
[From an agent](#from-an-agent) · [How it is built](#how-it-is-built) ·
[Documentation](#where-everything-else-is-written-down) ·
[Contributing](#contributing)

## Connections are not all the same thing

Most tools model a perfboard connection as "a wire". Perfboard has six physically
distinct ways to join two points, each with its own cost, limits and failure modes — and
modelling that difference is what lets the router produce a layout that is pleasant to
actually solder:

| | what it is | notes |
|---|---|---|
| lead bend | a component leg bent to a nearby hole | effectively free, 3–4 holes |
| **solder trace** | adjacent pads joined with solder alone | orthogonal only; ~0.6 mm to the next pad |
| **solder trace, wired** | the same, over a tinned-wire spine | ~10× lower resistance, no length limit |
| bare wire | tinned wire on the solder side | cannot cross another bare conductor |
| insulated wire | may cross freely | costs preparation time |
| top jumper | insulated jumper over the component side | visible, occupies body space |

The 0.6 mm gap to the neighbouring pad is why solder traces are both so useful and so
easy to get wrong. Perfboard Studio scores that risk into the router's cost function, and turns
every flagged spot into a measurement step in the build guide.

## Both faces, and the third dimension

The solder side is where the copper is, so it is a first-class view rather than a mirror
mode — and copper on the face you are *not* looking at is hatched, because a board is
opaque and a trace drawn solid says *this is in front of you*.

![The solder side, with far-side copper hatched](https://raw.githubusercontent.com/medinstech/perfboard-studio/main/docs/images/editor-solder-side.png)

The 3D view is a checking tool, not a picture. Three rules exist that a top-down view
cannot see at all: a part too tall for the case, a jumper trapped under a body that will
be soldered down on top of it, and a heat-sensitive part sitting too close to a hot one.

![The same board in 3D](https://raw.githubusercontent.com/medinstech/perfboard-studio/main/docs/images/board-3d.png)

## Draw the circuit first

The board says where everything goes. The schematic panel (`Ctrl+5`) says *what you are
building* — and it is where you say it: **Add Part**, **Wire** two pins, **Place on the
Board**. The circuit comes first and the layout second, which is how every other EDA tool
works and is the order this one could not do until now.

![The NE555 astable, drawn from its netlist](https://raw.githubusercontent.com/medinstech/perfboard-studio/main/docs/images/schematic.png)

**The sheet is derived, never stored.** No symbol positions live in the file, so there is
no second copy of the circuit to keep in step with the netlist and nothing to lay out by
hand. Ground and power become rail symbols instead of wires, which is the difference
between a sheet you can read and eleven lines crossing everything. Polarity comes from the
parts library's own pin names, so an LED's cathode and a diode's cathode both end up on the
barred end — they are opposite pins, and a rule that guessed from pin 1 would draw one of
them backwards. A part whose pinout the library does not record, like a TO-92, is a
labelled box: drawing a transistor there would be asserting which lead is the base.

It also cross-probes: click a symbol and that part is selected on the board, click a wire
and its net lights up in both places. LVS saying *net VOUT is open* is a great deal more
useful when you can look at VOUT.

**And it leaves the window.** *File ▸ Export Schematic…* writes the sheet beside the
document three ways: SVG to embed or edit, PDF to print and keep next to the board, PNG to
paste into the message that asks somebody why the circuit does not work. All three come out
of the same SVG, so they cannot disagree about what the circuit is — and the exported sheet
is black on white rather than the panel's light-on-dark, because the rail symbols already
say which rail sinks and which sources, and a photocopier keeps shapes rather than colours.

## The guide has an order, and you can watch it

![The NE555 board assembling itself: parts first, then the board turns over and the copper goes on](https://raw.githubusercontent.com/medinstech/perfboard-studio/main/docs/images/assembly.gif)

Parts go in **shortest first** — a tall part fitted early stops the board lying flat on
the bench while the short ones are soldered. Then the board is turned over and the copper
goes on, and ICs are last for heat and ESD. A jumper that would end up trapped under a
part body is moved to the *first* phase, because by the time that part is down it is too
late.

The animation turns the board over halfway through for the same reason you would: a
perfboard is opaque, and fourteen of this build's twenty-two steps happen on the face you
cannot see from above. It is generated by playing the guide back through the same function
the 3D panel's assembly slider calls, so it cannot show an order the guide does not
actually give you.

## Running it

It is a desktop application, so the ordinary way to get it is to install one. No Python
required.

**[⬇ Download the latest release](https://github.com/medinstech/perfboard-studio/releases/latest)**

| | |
|---|---|
| **Windows** | an `.exe` installer |
| **macOS** | a `.dmg`, Apple silicon |
| **Linux** | an `.AppImage`, x86_64 |

Each is built and smoke-tested by the tag that produced it. **None
of them is code-signed**, so each warns on first run and the release notes say how to get
past it — a Windows EV certificate is ~$300/year and Apple notarization $99/year, and
neither is bought yet. See [docs/RELEASING.md](https://github.com/medinstech/perfboard-studio/blob/main/docs/RELEASING.md).

The interface speaks **English and Turkish** (`--lang tr`, or follow the system locale).

### From PyPI

For the two platforms with no build — an Intel Mac, Linux on ARM — and for anyone who
would rather not click past a signing warning. Needs **Python 3.12+**:

```sh
uv tool install perfboard-studio    # or: pipx install perfboard-studio

perfboard-studio                    # launch on a blank board
perfboard-studio some/board.perf    # ...or open a document
perfboard-studio --version
```

**`uv tool` or `pipx`, not a bare `pip install`**, because this is an application and not
a library. Both put it in an environment of its own and `perfboard-studio` on your PATH, where
`pip install` would either put 400 MB of Qt and VTK into a shared `site-packages` or, on
Debian, Ubuntu and Fedora, be refused outright by the system Python (PEP 668). From a
clone, `pip install -e .` inside a virtualenv.

Qt and VTK are most of that 400 MB. There is no smaller build, because the 3D view is a
checking tool the application depends on rather than an optional extra.

### A board from nothing

Open the schematic panel (`Ctrl+5`) and draw the circuit: **Add Part** for each part,
**Wire** to click two pins together, then **Place on the Board**. From there
**Place → Auto-place Board** (`Ctrl+Shift+A`), **`Ctrl+R`** to route, and
**File → Export Build Guide** (`Ctrl+B`). No KiCad anywhere in that.

With a circuit that already exists, start at **File → Import KiCad Netlist** on
`examples/ne555-astable.net` and accept the offered placement instead. That is the exact
sequence the screenshots above come out of — see
[`tools/screenshots.py`](https://github.com/medinstech/perfboard_studio/blob/main/tools/screenshots.py).

### Or open one that is already built

[Four examples](https://github.com/medinstech/perfboard-studio/blob/main/examples/README.md) ship as both the netlist and the finished board:

```sh
perfboard-studio examples/lm317-supply.perf
```

| | what it is there to show |
|---|---|
| `ne555-astable` | the starting point — a 555 flashing an LED |
| `lm317-supply` | a TO-220 regulator, so the heat rule has something to measure |
| `lpb1-booster` | built on **FR-2**, the phenolic board whose pads lift |
| `arduino-io-shield` | two headers, which is what a shield mostly is |

All four route to completion, match their schematics under LVS and carry no DRC error —
`tests/test_examples.py` asserts it on every commit.

### From an agent

The MCP server drives the identical command bus, so undo works across both:

```sh
claude mcp add perfboard-studio -- uvx --from "perfboard-studio[mcp]" perfboard-studio-mcp
```

Nothing has to be installed first — `uvx` fetches the package into its own cache. From a
clone it is `pip install -e ".[mcp]"` and then `claude mcp add perfboard-studio -- perfboard-studio-mcp`.

Fifty-one tools, every hole addressed the way people talk about perfboard (`A1`, `C7`,
`AC12`) and never as raw coordinates. See [docs/MCP.md](https://github.com/medinstech/perfboard-studio/blob/main/docs/MCP.md) for the tool list,
the JSON config other clients want, and the rest of the setup.

### Headless

Renders 2D/3D/PDF to files, runs DRC and LVS and prints timings, with no display. It is
how the visual output is exercised in CI, and the fastest way to check that a rendering
change did not crash:

```sh
python -m perfboard_studio.ui.main --headless tools/diffcheck/golden/dense.perf
```

## How it is built

The document is **immutable** and every mutation is a command dispatched through one
bus — which is what makes undo work across a mixed human/agent session. The engine is
**pure**: no clock, no RNG, no filesystem, no Qt or VTK below `ui/`. The placer's
annealing is seeded, so the same document and the same seed give the same board.

That purity is load-bearing rather than decorative. This Python engine is a port of the
TypeScript one still in `packages/`, and its acceptance criterion was never "the tests
pass" but "it produces byte-identical results to the implementation it replaces" —
golden fixtures in `tools/diffcheck/`, down to the last IEEE-754 double.

```
src/perfboard_studio/            the engine: document model, command bus, connectivity,
                           router, autorouter, placer, DRC, LVS, persistence
src/perfboard_studio/guide.py    the soldering guide, and guide_export.py for HTML/CSV/JSON
src/perfboard_studio/stripboard.py  the board whose copper arrives joined, and striproute.py
                           for the cuts-and-links planner that designs on one
src/perfboard_studio/parsers/    KiCad netlist importer
src/perfboard_studio/ui/         Qt application: 2D editor, VTK 3D view, 1:1 PDF export,
                           and headless.py, the no-display run CI checks the output with
src/perfboard_studio/mcp/        the MCP server (docs/MCP.md)
examples/                  a netlist to import
tests/                     ~2080 tests; the engine is mypy --strict clean
packages/                  the original TypeScript engine, kept as the reference the
                           Python port is proved against
```

The 61 THT footprints are **generated from numeric parameters**, not shipped as assets —
no mesh library, no share-alike licence to inherit. The same spec that draws a part in 2D
extrudes its body in 3D, so the two cannot disagree.

**A part that is not among the 61 is described, not installed.** *Custom Part…* asks for a
pin grid and three dimensions and hands back an identifier that carries them:
`box-4x2-p1-r3-15x10x8` is a four-by-two pin grid, three holes between the rows, in a
15 × 10 × 8 mm body. Nothing is stored — the identifier *is* the definition — so a board
using a part nobody else has still opens as that part on their machine, with no library to
install and nothing to go missing.

## Where it is going

Done: the editor, the library, connectivity and LVS, DRC, the router and the placement
optimiser, the build guide with rendered step images and assembly playback, the 1:1 PDF
export, the schematic panel and the sheet export beside it, parts described by their own
measurements when the library does not have them, crash recovery, the MCP server, TR/EN
localisation, the three-platform packaging that a `v*` tag
runs, and the update check that tells you a release exists and fetches it (**Help ▸ Check
for Updates**; it verifies the download against the release's `SHA256SUMS` and then hands
it to you — running it stays your click).

Next, in the order [PLAN.md](https://github.com/medinstech/perfboard-studio/blob/main/PLAN.md) §11 puts them:

- **The dogfood build (M5).** Somebody has to solder a real board from a generated guide.
  Until that has happened, every claim on this page is a claim about software rather than
  about a working circuit. It is also the one thing on this list that a stranger can do
  for the project — there is [an issue template for it](https://github.com/medinstech/perfboard-studio/blob/main/.github/ISSUE_TEMPLATE/board_i_could_not_build.yml).
- **Code signing.** A Windows EV certificate is ~$300/year and Apple notarization
  $99/year, so until then the installers warn on first run and the release notes say how
  to get past it.

## Where everything else is written down

| | |
|---|---|
| [docs/MCP.md](https://github.com/medinstech/perfboard-studio/blob/main/docs/MCP.md) | the 51 MCP tools, grouped with the reason each one exists, and the client config for Claude Code, Claude Desktop, Cursor and Antigravity |
| [examples/README.md](https://github.com/medinstech/perfboard-studio/blob/main/examples/README.md) | what each of the four example boards is there to demonstrate |
| [CHANGELOG.md](https://github.com/medinstech/perfboard-studio/blob/main/CHANGELOG.md) | every release, and what an unreleased build is accumulating towards the next one |
| [docs/RELEASING.md](https://github.com/medinstech/perfboard-studio/blob/main/docs/RELEASING.md) | the tag ritual, and what `release.yml` builds out of it on three platforms |
| [docs/prior-art.md](https://github.com/medinstech/perfboard-studio/blob/main/docs/prior-art.md) | the tools that already exist in this space, and the licence boundary this project keeps from them |
| [CONTRIBUTING.md](https://github.com/medinstech/perfboard-studio/blob/main/CONTRIBUTING.md) | running the suite, which checks are gates and which are reports |
| [SECURITY.md](https://github.com/medinstech/perfboard-studio/blob/main/SECURITY.md) · [CODE_OF_CONDUCT.md](https://github.com/medinstech/perfboard-studio/blob/main/CODE_OF_CONDUCT.md) | reporting a vulnerability, and how people are expected to behave here |
| [PLAN.md](https://github.com/medinstech/perfboard-studio/blob/main/PLAN.md) | the original project plan, **written in Turkish** and kept as written, so what was predicted can be read beside what came out |
| [CLAUDE.md](https://github.com/medinstech/perfboard-studio/blob/main/CLAUDE.md) | why the code is shaped the way it is. Written for agents working in the repository, and the most useful thing here for a person about to change something |

## Contributing

Issues and pull requests are welcome. Please read [CONTRIBUTING.md](https://github.com/medinstech/perfboard-studio/blob/main/CONTRIBUTING.md)
first — it covers how to run the suite, which checks are gates and which are not, and one
licence boundary that matters more here than in most projects: **do not read or port code
from the GPL-licensed tools in this space.** Perfboard Studio is clean-room with respect to
them, and that has to stay true. The record is in [docs/prior-art.md](https://github.com/medinstech/perfboard-studio/blob/main/docs/prior-art.md).

## Licence

Apache-2.0. See [LICENSE](https://github.com/medinstech/perfboard-studio/blob/main/LICENSE) and [NOTICE](https://github.com/medinstech/perfboard-studio/blob/main/NOTICE).
