> ## Documentation Index
> Fetch the complete documentation index at: https://docs.pcb.new/llms.txt
> Use this file to discover all available pages before exploring further.

# Packages

> Package management, workspaces, and dependency resolution

Package versions identify immutable source snapshots. A dependency on
`component-lib@0.3.2` selects the same source for every build until the manifest
changes.

## Repository structure

A board repository has a root `pcb.toml` with `[workspace]` and `[board]`
metadata, a board `.zen` entrypoint, and generated KiCad files under `layout/`.
Create one with `pcb new board <NAME> <REPO_URL>`.

A registry repository has a root `[workspace]` but no `[board]`. Both repository
types can own reusable packages under `components/` and `modules/`. Each package
has its own `pcb.toml` and `.zen` entrypoints; component packages also carry
their symbols and footprints. `vendor/` holds vendored dependencies.

## Version policy

PCB packages use semantic versions with hardware-specific compatibility rules:

| Change                            | Allowed contents                                                                                   |
| --------------------------------- | -------------------------------------------------------------------------------------------------- |
| Patch, such as `0.3.1` to `0.3.2` | Documentation and metadata changes that do not alter connectivity, layout, or electrical behavior. |
| Minor, such as `0.3` to `0.4`     | New compatible behavior after `1.0`; a breaking compatibility lane before `1.0`.                   |
| Major, such as `1.x` to `2.0`     | Breaking changes such as changed pins, interfaces, or removed behavior.                            |

Compatibility families are minor-version lanes before `1.0` (`0.3.x`, `0.4.x`)
and major-version lanes afterward (`1.x`, `2.x`). Do not publish breaking changes
within a family.

`pcb sync` records the selected dependency graph in `pcb.toml`, resolving branches
and commits to immutable pseudo-versions. Builds reuse this hydrated state rather
than selecting newly published versions.

## Workspace package discovery

Starting at the workspace root, `pcb` searches at most eight directory levels
and treats each descendant directory containing `pcb.toml` as a package.

`[workspace].exclude` controls discovery:

```toml theme={null}
[workspace]
pcb-version = "0.4"
exclude = ["scratch/**", "experiments/old-board"]
```

`pcb` does not search inside an excluded directory. It also skips generated and
cache directories such as
`.git`, `.pcb`, `vendor`, `target`, `node_modules`, and `fork`.

## Coexisting versions

A build can contain incompatible families of one package, such as
`component-lib@0.3.x` and `component-lib@1.x`. The resolver keeps separate copies
for their dependents. Their values have distinct types and cannot cross the
compatibility boundary.

## Minimal Version Selection

Minimal Version Selection (MVS), based on [Go modules](https://go.dev/ref/mod),
selects the highest explicit minimum required within each package family:

```
Board
├── component-lib >= 0.3
└── regulator >= 1.0
    └── component-lib >= 0.3.2
```

The board requires `component-lib >= 0.3.0`, while `regulator` requires
`component-lib >= 0.3.2`. MVS therefore selects `0.3.2`, even if `0.3.9` exists.
Require a newer version explicitly when the project is ready to test it:

```toml theme={null}
[dependencies]
"github.com/acme/component-lib" = "0.3.9"
```

Resolution starts with all workspace packages' direct dependencies, fetches
selected manifests, and raises versions to satisfy transitive requirements until
the graph stops changing. It then traces the final graph from workspace roots,
discarding superseded versions. MVS is deterministic and does not backtrack.

## Import paths as identity

Import paths serve as globally unique package identifiers:

```python theme={null}
load("@stdlib/units.zen", "Voltage")
load("github.com/myorg/components/capacitor.zen", "Capacitor")
```

Paths identify the owner and repository, without versions. Declare versions in
`pcb.toml` so imports remain stable across upgrades:

```toml theme={null}
[dependencies]
"code.diode.computer/diode/registry/components/ti/tps54331" = "1.0"
```

## Hydrated manifests

Workspaces store resolved dependency state in `pcb.toml`. `pcb sync` updates:

* `[dependencies]`: direct dependencies the package imports or explicitly owns.
* `[dependencies.indirect]`: the tool-managed MVS closure needed to build it.

```toml theme={null}
[dependencies]
"code.diode.computer/diode/registry/modules/Regulator" = "1.0"

[dependencies.indirect]
"code.diode.computer/diode/registry/components/TPS54331@1" = "1.0.2"
"code.diode.computer/diode/registry/modules/Feedback@1" = "1.1.0"
```

The `@1` suffix is a compatibility lane. It allows multiple
incompatible versions of the same package path to coexist while keeping the
selected version exact.

Do not edit `[dependencies.indirect]` by hand. Commit hydrated `pcb.toml` files.

## Vendoring (`[workspace].vendor`)

Vendoring policy is controlled by the root workspace manifest:

```toml theme={null}
[workspace]
vendor = ["github.com/myorg/**"]
```

* `pcb publish` uses `[workspace].vendor` patterns when staging release sources.
* `pcb sync` vendors packages matched by `[workspace].vendor`.
* `pcb vendor` without `--all` uses `[workspace].vendor`.
* `pcb vendor --all` vendors everything.
* Read commands such as `pcb build`, `pcb layout`, `pcb test`, `pcb open`, and
  `pcb bom` do not change `vendor/` or rewrite dependency manifests.

## Workspace name (`[workspace].name`)

Workspace manifests can override the Diode workspace name used for board
release uploads:

```toml theme={null}
[workspace]
name = "my-workspace"
```

If `name` is omitted, `pcb publish` derives the workspace name from the first
path segment of `[workspace].repository`. For example,
`anything.com/XYZ/boards/MyBoard` uses `XYZ`.

## Endpoint (`[workspace].endpoint`)

Workspace manifests can override the Diode host suffix used by CLI commands
that access Diode services:

```toml theme={null}
[workspace]
endpoint = "diode.computer"
```

* `endpoint = "diode.computer"` resolves application and API URLs under
  `app.diode.computer` and `api.diode.computer`.
* The setting applies to workspace-aware commands such as `pcb auth`, `pcb bom`,
  `pcb publish`, and routing commands.
* Authentication is scoped to the resolved endpoint. Authentication for one
  endpoint does not overwrite tokens for another.

## BOM matching (`[workspace.bom]`)

`pcb bom` availability queries use strict BOM matching by default, requiring
exact MPN matches. Workspace manifests can opt out to use fuzzy matching:

```toml theme={null}
[workspace.bom]
strict = false
```

## Registry search scope

Registry-backed `pcb search` searches the public Diode registry and the
registries configured by `[workspace].repository`.

* `pcb search --registry code.diode.computer/diode/registry ...` overrides the default
  scope for that invocation.
* Repeat `--registry` to search more than one registry.

## Pseudo-versions

Pseudo-versions identify unreleased commits while preserving version ordering.

The format is `v<base>-0.<timestamp>-<commit>`.

```toml theme={null}
[dependencies]
# Branch reference - resolved to pseudo-version
"github.com/acme/component-lib" = { branch = "main" }

# Specific commit
"github.com/acme/component-lib" = { rev = "a1b2c3d4" }
```

Resolution produces a version such as:

```
v0.3.15-0.20251120004415-137e2dcabc28…   # commit hash shortened here for readability
```

`pcb sync` writes the resolved pseudo-version back to the package manifest with
the full 40-character commit hash.

The base version (0.3.15) is the next patch version after the most recent tag
reachable from that commit. This places the pseudo-version after its base tag and
before the next release.
If the package has never been tagged, pseudo-versions start in the `0.1.1`
family (for example `0.1.1-0.<timestamp>-<commit>`), one patch above the
initial unpublished release version `0.1.0`.

Pseudo-versions participate fully in MVS. If one package requires `component-lib@0.3.14`
and another requires the pseudo-version above, MVS selects the pseudo-version
(it is higher). This permits testing an unreleased change without retaining a
mutable branch reference in the hydrated graph.

Use a tagged release for production dependencies when one is available.

## Commands

### `pcb migrate`

Runs project migrations using the latest stable `pcbc` toolchain, regardless of
the workspace's current `pcb-version` lane. After all migrations succeed, the
command updates `[workspace].pcb-version` in `pcb.toml` to the target toolchain
lane.

```bash theme={null}
pcb migrate
pcb migrate ./path/to/workspace
```

### `pcb sync`

Reconciles imports and hydrates package manifests. Run this after adding or
removing imports or changing dependency versions.

```bash theme={null}
pcb sync                    # Sync packages under the current workspace/package
pcb sync --check            # CI guard: fail if pcb.toml or vendor/ is out of sync
pcb sync -v                 # Print changed manifests
```

The command also downloads selected packages into the cache and vendors packages
matched by `[workspace].vendor`.

`pcb sync --check` always verifies the whole workspace, regardless of the
current directory, and writes neither `pcb.toml` nor `vendor/`. It detects
missing or stale vendored package versions; it does not verify the contents of
vendored versions that are already present.

### `pcb add`

Adds or upgrades a direct dependency for the package in the current directory.

```bash theme={null}
pcb add github.com/acme/regulators/Buck@1.2.3
pcb add github.com/acme/regulators/Buck@latest
pcb add -u                              # Upgrade all direct remote dependencies
pcb add -u github.com/acme/regulators/Buck
```

`pcb add` rewrites the direct dependency entry and rehydrates the package's
dependency closure.

### `pcb build`

Builds a board or workspace package.

```bash theme={null}
pcb build                    # Build default board
pcb build WV0002.zen         # Build a specific board file
pcb build --offline          # Build using only cached/vendored packages
```

`pcb build` checks that the hydrated state is sufficient and does not rewrite
`pcb.toml` or `vendor/`. Use `pcb sync` or `pcb vendor` to update dependency
state.

### `pcb list`

Lists read-only package dependency information.

```bash theme={null}
pcb list -m -u                              # Show compatible updates for direct dependencies
pcb list -m -versions github.com/acme/foo   # Show published versions for a dependency
```

`pcb list -m -u` must be run from a package directory. It reports direct remote
dependencies only, showing the latest stable version in the same compatibility
lane and the latest newer breaking lane when available. It does not update manifests.

### `pcb update`

`pcb update` is disabled. Use [`pcb add -u`](#pcb-add) instead.

### `pcb publish`

Publishes changed packages with annotated Git tags.

```bash theme={null}
pcb publish                  # Publish all changed packages
pcb publish --bump=infer     # Infer bumps from commit history and dependency waves
pcb publish --bump=infer -y  # Skip the final publish confirmation
pcb publish --force          # Skip preflight checks
```

A package requires publication when:

* No version tag exists.
* Its content hash differs from the published tag.
* Its `pcb.toml` hash differs from the published tag.

Versions are computed automatically:

* **Unpublished:** Start at `0.1.0`.
* **Published packages:** Apply the requested semantic-version bump: `patch`,
  `minor`, or `major`.
* **`--bump=infer`:** Infer each bump from conventional commits since the last
  tag, then raise dependent bumps to at least the highest bump among published
  internal dependencies.
* **`-y` / `--yes`:** Skip the final confirmation prompt.

Packages are published in dependency order. Packages with no changed
dependencies are published first; their dependents follow after manifest
updates.

### `pcb info`

Displays workspace and package information.

```bash theme={null}
pcb info                     # Show workspace summary
pcb info --format json       # Machine-readable output
```
