Files
diodeinc__pcb/README.md
T
Lenny Khazan 6efd247cae feat(pcb): add native KiCad URL launcher (#983)
* feat(pcb): add native KiCad URL launcher

* fix(pcb): harden launcher recovery choices

* fix(pcb): prevent concurrent recovery sessions

* fix(pcb): guard restored editor sessions

* refactor(pcb): extract shared pcb-diode-uri and pcb-native-dialog crates

pcb-launcher's URI validation re-implemented pcb-diode-api's SandboxFileUri
parsing; move that parser into a tiny pcb-diode-uri crate both can use, and
give the trusted-host allowlist a single home there. Likewise collapse the
duplicated osascript/zenity/kdialog/PowerShell dialog machinery from
pcb-launcher and pcbc's recovery dialog into a pcb-native-dialog crate.
Also drop the launcher's redundant staged-app cleanup (the Drop guard
covers it), the duplicate log chmod, the Debug-formatted log header, and
a clippy for_kv_map lint in the interposer pattern test.

* fix(pcb): block recovery while a recoverable session's editor is open

A recoverable stop now deliberately leaves KiCad running, so the
still-open-editor guard must cover Recoverable sessions too — otherwise
Restore reuses the same local layout dir while the first KiCad instance
still has it open. Also match the tracked pid's process name (open /
pcbnew / kicad) instead of bare liveness, so a recycled pid cannot
permanently wedge the board.

* refactor(pcb): simplify launcher install and open plumbing

Split install_shim_launcher into fetch / stage / replace helpers so the
Windows backup-rename dance is a reusable replace_executable_with_backup,
fold pcb-kicad's duplicated per-OS pcbnew command construction into one
builder, share a single Download-style helper in install.ps1 the way
install.sh already does, dedupe the recovery-cancel wind-down, and fix
the README's launcher wording.

* refactor(pcb): re-export diode URI types without a module alias

Nothing consumed the pcb_diode_api::diode_uri path; re-export the types
directly from pcb-diode-uri instead of aliasing the whole crate.

* refactor(pcb): trust *.diode.computer in release, all hosts in debug

Replaces the enumerated host allowlist: release launchers accept any
*.diode.computer subdomain (portless, so preview and gov endpoints work
without listing them), while debug builds trust every host so local API
stacks need no special-casing.
2026-08-26 10:46:19 -04:00

6.4 KiB

pcb

pcb is a command-line tool for circuit board projects written in Zener. Zener is a Starlark-based language for describing PCB schematics; pcb builds those designs, manages dependencies, and generates KiCad layout files.

Documentation | Language reference

Installation

Install the pcb launcher on macOS, Linux, or WSL2:

curl -fsSL https://raw.githubusercontent.com/diodeinc/pcb/main/install.sh | bash

For native Windows, run this command in PowerShell:

powershell -ExecutionPolicy Bypass -c "irm https://raw.githubusercontent.com/diodeinc/pcb/main/install.ps1 | iex"

The launcher downloads and runs the pcbc toolchain requested by each project. The Unix installer writes pcb to $HOME/.local/bin by default. The Windows installer writes pcb.exe to %USERPROFILE%\.pcb\bin by default. Set PCB_INSTALL_DIR to choose a different directory.

The installer also registers the diode:// URL scheme for the current user. The Diode registry can use these links to open sandbox layouts in KiCad without a terminal. pcb self update updates and re-registers the launcher together with the pcb shim. If a browser-launched open fails, the launcher displays the error and records command output in ~/.pcb/pcb-launcher.log (or %USERPROFILE%\.pcb\pcb-launcher.log on Windows).

KiCad 10.x is required only for generating and editing layouts. Building and validating Zener files does not require KiCad.

Native Windows support is experimental. Use WSL2 if a command does not work in the native environment.

Toolchain management

pcb manages pcbc, the standard library, and bundled sidecars such as pcb-rectify as one versioned toolchain.

Workspace commands use the toolchain selected by pcb-version. pcb auth instead uses the latest stable toolchain; an explicit +<toolchain> override still wins. pcb self and pcb toolchain run directly in the launcher.

pcb toolchain show                 # Show the active and latest matching versions
pcb toolchain show --offline       # Use installed and cached data only
pcb toolchain install latest       # Install the latest stable toolchain
pcb toolchain prune --dry-run      # Preview removable downloads and old patches
pcb toolchain prune                # Remove them
pcb toolchain repair latest        # Validate and restore a toolchain

Install and repair accept latest, nightly, a lane such as 0.4, or an exact version such as 0.4.9. Pruning preserves the newest patch in each lane, the active version, prereleases, nightly, and local toolchains. pcb self update updates the shim and managed channels and fails if any requested update fails.

Developing from source

git clone https://github.com/diodeinc/pcb.git
cd pcb
cargo build -p pcb -p pcbc
./install.sh --local

Local installation registers diode:// links against the local toolchain. Installing or self-updating a release registers them against latest again.

Repository maintenance scripts are run by their explicit path, such as ./bin/embed-readme --check README.md; no shell environment activation is needed.

Quick start

Create blinky.zen:

# ```pcb
# [workspace]
# pcb-version = "0.4"
# ```

Resistor = Module("@stdlib/generics/Resistor.zen")
Led = Module("@stdlib/generics/Led.zen")

VCC = Power()
GND = Ground()
LED_ANODE = Net()

Resistor(name="R1", value="1kohm", package="0402", P1=VCC, P2=LED_ANODE)
Led(name="D1", package="0402", color="red", A=LED_ANODE, K=GND)
Board(name="blinky", layers=4, layout_path="layout/blinky")

Build the design:

pcb build blinky.zen

Generate a KiCad layout:

pcb layout blinky.zen

Repository layouts

Zener projects use one of two repository shapes.

Board repository

A board repository contains one board plus any local modules and components it owns:

MyBoard/
├── pcb.toml              # Workspace and board manifest
├── MyBoard.zen           # Board schematic
├── layout/               # KiCad layout files
├── modules/              # Reusable circuit modules
│   └── PowerSupply/
│       ├── PowerSupply.zen
│       └── pcb.toml
├── components/           # Custom component definitions
│   └── Manufacturer/
│       └── MPN/
│           ├── MPN.zen
│           └── pcb.toml
└── vendor/               # Vendored dependencies

Create one with:

pcb new board MyBoard https://github.com/myorg/MyBoard

Board repository pcb.toml:

[workspace]
repository = "github.com/myorg/MyBoard"
pcb-version = "0.4"

[board]
name = "MyBoard"
path = "MyBoard.zen"
description = "Replace with concise board description."

Registry repository

A registry repository contains reusable packages and no board:

registry/
├── pcb.toml              # Workspace manifest
├── components/           # Component packages
│   └── TPS54331/
│       ├── TPS54331.zen
│       ├── TPS54331.kicad_sym
│       ├── TPS54331.kicad_mod
│       └── pcb.toml
└── modules/              # Reusable module packages
    └── UsbCSink/
        ├── UsbCSink.zen
        └── pcb.toml

Registry pcb.toml:

[workspace]
repository = "github.com/myorg/registry"
pcb-version = "0.4"

Common commands

pcb new board <NAME> <REPO_URL>              # Create a board repository
pcb build [PATHS...]                         # Build and validate designs
pcb sync                                     # Reconcile imports and dependency manifests
pcb layout <FILE>                            # Generate layout files
pcb dfm <FILE> --pdk standard                # Check a .zen board for manufacturability
pcb import <KICAD_SCH|KICAD_PRO> <OUTPUT_DIR> # Import a KiCad schematic or project

Run pcb help or pcb help <command> for the full command reference.

License

Diode-authored code and docs are licensed under the MIT License except where otherwise noted. See LICENSE and THIRD_PARTY_NOTICES.md.

Acknowledgments