Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions content/docs/guides/using-with-swift.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ LPM.dev Registry speaks the [SE-0292 Swift Package Registry API](https://github.

- LPM CLI installed — see [Installation](/docs/installation).
- Swift toolchain installed.
- An lpm.dev account, logged in (`lpm login`).
- An lpm.dev account and `lpm login` for Private, Pool, or Marketplace packages. Free packages need no account.

## Installing a Swift package

Expand All @@ -22,7 +22,7 @@ lpm install --yes @lpm.dev/owner.swift-pkg # choose the first eligible targ
On the first Swift install in an unconfigured project, LPM CLI:

1. Sets the `lpmdev` scope to the LPM.dev Registry SE-0292 endpoint.
2. Passes the current LPM.dev Registry session to SPM.
2. Passes the current LPM.dev Registry session to SPM when protected access is required. Free releases skip this login.
3. Installs the Registry CMS signing certificate.
4. Configures the signing policy for the Registry hostname.
5. Checks access, updates `Package.swift`, resolves dependencies, and checks required products with the native dependency graph.
Expand All @@ -33,7 +33,7 @@ Every reinstall resolves dependencies, even when the declaration already exists.

A `Package.swift` in the current directory takes precedence over an unrelated parent `package.json`.

During later HTTPS installs, LPM CLI signs in to SPM again even when the Registry scope matches. A rejected stored bearer causes one session refresh and one login retry.
For protected HTTPS installs, LPM CLI signs in to SPM again even when the Registry scope matches. A rejected stored bearer causes one session refresh and one login retry.

The same routing applies in workspaces. Use `-w` for a root `Package.swift`, run from a member directory for that member, or use `--filter` to select Swift members. LPM CLI mutates, configures, reports, and runs `swift package resolve` from the same selected directory. In mixed JavaScript/Swift workspaces, Swift versions go only through SE-0292 while JavaScript versions retain normal `package.json` installation.

Expand Down
49 changes: 49 additions & 0 deletions content/docs/packages/free-distribution.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
title: Free distribution
description: "Install Free packages anonymously and understand publishing, reviews, private history, and hosting retention."
---

Free distribution makes a package available without an account, subscription, or purchase.

```bash
lpm install @lpm.dev/owner.free-package
lpm add @lpm.dev/owner.free-source --path ./src/vendor/free-source
```

Use [lpm install](/docs/packages/install) for dependencies, including native Swift packages. Use [lpm add](/docs/packages/add) to copy source files.

## Access and credentials

An available Free release needs no login. A stale token does not block its metadata or downloads. Private, Pool, and Marketplace dependencies still require their own access.

If a requested version is unavailable publicly, LPM CLI can refresh a stored login to recover the publisher's access to private history. Successful public installs do not refresh the login. A version range can therefore select a public release even when the publisher has a newer private release. To install private history, request its version explicitly with a valid publisher login.

Each install checks current availability, including when package files are cached. A quarantined or removed release cannot be installed from its old registry metadata.

Free packages generate no Pool revenue. A project can mix Free and protected packages; protected dependencies retain their normal access requirements.

## Publishing and private history

Packages start private. After publishing a release, select the distribution mode in the package's dashboard settings.

Free publishing requires paid Pro coverage for a personal package, or eligible coverage from the owning organization. An unpaid trial does not qualify. Free distribution is separate from the Free account plan.

When you select Free, Pool, or Marketplace, only the latest eligible release enters activation review. Earlier private releases stay publisher-only and are absent from public metadata and pages.

Future releases enter review individually. This includes a new lower-version backport. For example, after promoting `2.0.0`, you can publish public `1.5.0`; the previously private `1.0.0` stays hidden.

Free activation requires publication security review and dependency checks. Identified dependencies from LPM.dev Registry must themselves be available Free releases. Aliases, development dependencies, peers, bundles, source configuration, and Swift declarations are included.

Use [lpm publish --wait](/docs/packages/publish) when automation must wait for availability. A held or rejected upload does not replace a previously available release.

## Hosting retention

When paid coverage ends, existing Free releases remain downloadable. The Registry automatically deprecates the package after 30 days and schedules hosted-file removal after 365 days.

The clock starts when paid coverage ends, including the end of a paid period after cancellation. Renewal before removal clears this automatic schedule. Author deprecation and security restrictions remain separate.

Removal preserves package identities and version records. Names cannot be reused, and renewal after removal does not restore the files.

Security rescans continue after paid coverage ends. Quarantine blocks known releases containing affected bytes, including nested bundles. The Registry preserves the published archive; a corrected release needs a new version.

Free distribution is permanent. It cannot change to Private, Pool, or Marketplace. Distribution does not replace the package's software license.
14 changes: 13 additions & 1 deletion content/docs/packages/install.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -1029,9 +1029,21 @@ The workspace-root preflight also runs for [`lpm rebuild`](/docs/packages/rebuil

Plus the [global flags](/docs/commands#global-flags): `--token`, `--registry`, `--json`, `--verbose`, `--insecure`.

## Free packages

Free releases from LPM.dev Registry install without login:

```bash
lpm install @lpm.dev/owner.free-package
```

A stale credential does not block an available Free release. Protected dependencies still require access. Cached packages receive a current availability check, so quarantine or hosted-file removal can stop a reinstall.

See [Free distribution](/docs/packages/free-distribution) for reviews, private history, and hosting retention.

## Pool install reports

After a successful install, LPM CLI reports the resolved graph for `@lpm.dev/*` packages to the LPM.dev Registry. The report follows actual dependency and peer targets, including overrides and npm aliases. Downloads from a failed install do not create Pool credit.
After a successful install, LPM CLI reports the resolved graph for `@lpm.dev/*` packages to the LPM.dev Registry. The report follows actual dependency and peer targets, including overrides and npm aliases. Downloads from a failed install do not create Pool credit. Free packages never earn Pool credit. A graph containing only Free registry releases can be reported without authentication; mixed graphs retain the applicable access checks.

Older LPM CLI versions that send only package roots remain compatible. Their reports credit eligible roots, but can omit credit for transitive packages. Access checks still apply.

Expand Down
1 change: 1 addition & 0 deletions content/docs/packages/meta.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"download",
"resolve",
"---Specialized integrations---",
"free-distribution",
"pool",
"quality",
"swift-registry",
Expand Down
6 changes: 4 additions & 2 deletions content/docs/packages/publish.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ description: "Publish a package to LPM.dev Registry, npm, GitHub Packages, or a
lpm publish [--wait [--wait-timeout <SECONDS>]] # alias: lpm p
```

Packs the current directory and uploads it to a registry. By default, the target is **LPM.dev Registry** (where every package is private until you flip distribution to Pool or Marketplace). Publish elsewhere with `--npm`, `--github`, `--gitlab`, or `--publish-registry`.
Packs the current directory and uploads it to a registry. By default, the target is **LPM.dev Registry** (where every package is private until you select Free, Pool, or Marketplace distribution). Publish elsewhere with `--npm`, `--github`, `--gitlab`, or `--publish-registry`.

The final artifact for every target is scanned for hardcoded secrets. When LPM.dev Registry is one of the targets, LPM CLI also computes the local quality score and enforces `--min-score`. Normal npm, GitHub Packages, GitLab Packages, and custom-registry publishes do not run that quality gate.

Expand Down Expand Up @@ -124,7 +124,9 @@ Verify the existing release in the registry. To publish different contents, choo

An LPM.dev Registry version can enter a processing state after upload. A private version can enter a short security cooldown after a publish-source change.

Pool and Marketplace versions can require publication review before they become public.
Free, Pool, and Marketplace versions require publication review before they become public.

Changing a private package to public distribution reviews only its latest eligible version. Earlier private history stays publisher-only. Future releases enter review individually, including lower-version backports. Free publishing also requires eligible paid coverage and dependency admission. See [Free distribution](/docs/packages/free-distribution).

For a pending version, LPM CLI shows these separate values:

Expand Down
4 changes: 3 additions & 1 deletion content/docs/packages/swift-package-registry.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,11 @@ One eligible target is selected automatically. With multiple eligible targets, a

Use [`lpm install`](/docs/packages/install) for native Swift dependencies. Use [`lpm add`](/docs/packages/add) to copy source files into your project.

Free Swift releases support anonymous version listings, manifests, and archives. Certificate and signing-trust verification still apply. Protected releases require authentication.

## Pool accounting

After a successful native install, LPM CLI reports the resolved dependency graph. LPM.dev Registry calculates Pool depth from that graph and verifies download evidence for each registry package. Git dependencies remain in the graph so a registry dependency behind a Git package receives credit at the correct depth.
After a successful native install, LPM CLI reports the resolved dependency graph. LPM.dev Registry calculates Pool depth from that graph and verifies download evidence for protected registry packages. Free packages require no download evidence and receive no Pool credit. Git dependencies remain in the graph so a registry dependency behind a Git package receives credit at the correct depth.

A direct SwiftPM or Xcode archive download records provisional Pool credit at depth zero. Those clients do not report dependency depth. A later LPM CLI install replaces provisional credit with the resolved graph. Repeated downloads and reports do not create another credit for the same user, package, and accounting month. Owner and organization-member access do not earn Pool credit for the publisher.

Expand Down
10 changes: 5 additions & 5 deletions content/docs/packages/swift-registry.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ lpm swift-registry --force # repair stale/corrupt state or refresh the cert

Most users do not need to run this command before installing a package. [`lpm install`](/docs/packages/install) automatically configures Swift Package Manager (SPM) when it adds a Swift package from LPM.dev Registry.

Use `lpm swift-registry` when setup needs to be repaired or rerun explicitly. Use `--force` after a documented certificate rotation or when Registry configuration or the local certificate may be stale or corrupt. Sign in with [`lpm login`](/docs/infra/login) before resolving a Swift package; LPM.dev Registry requires authentication for every Swift package request.
Use `lpm swift-registry` when setup needs to be repaired or rerun explicitly. Use `--force` after a documented certificate rotation or when Registry configuration or the local certificate may be stale or corrupt. Sign in with [`lpm login`](/docs/infra/login) for Private, Pool, or Marketplace packages. Free releases can be installed anonymously.

## Normal install flow

Expand All @@ -21,7 +21,7 @@ lpm install @lpm.dev/owner.swift-pkg

On the first install, LPM CLI sets the `lpmdev` Registry scope and installs the signing certificate. It also configures signing trust, updates `Package.swift`, and resolves the dependency.

During each HTTPS setup pass, LPM CLI signs in to SPM with the current Registry session. It does this even when the Registry scope already matches.
Automatic setup skips SPM login when all requested releases allow anonymous access. Certificate and signing-trust checks still run. Protected installs sign in with the current Registry session, including when the scope already matches.

For an Xcode install, automatic setup also sets the global `lpmdev` scope. This lets the enclosing Xcode workspace resolve dependencies outside the generated wrapper. See [Xcode projects and workspaces](/docs/guides/using-with-swift#xcode-projects-and-workspaces).

Expand All @@ -32,15 +32,15 @@ LPM CLI accepts the global `--token <TOKEN>` flag for explicit setup and automat
Four setup steps. Scope, SPM login, certificate, and signing-trust failures abort an explicit run. A failed session refresh also aborts the command:

1. **Set the registry for the `lpmdev` scope.** Runs `swift package-registry set --scope lpmdev <registry-url>/api/swift-registry`. Adds `--allow-insecure-http` only for `http://` registry URLs (local dev); the hosted LPM.dev Registry endpoint is HTTPS-only.
2. **Log in.** Resolves the LPM.dev Registry bearer token through the standard LPM CLI session. It writes the token to a temporary file and calls `swift package-registry login --token-file <path> --no-confirm`. On Unix, the file mode is `0600`. LPM CLI removes the file after SPM exits, so the bearer does not appear in process arguments. This step runs only for HTTPS because SPM refuses to send authentication over HTTP. If no token is found, this step warns and is skipped. Setup can finish, but every Swift package request returns `401` until you run `lpm login`.
2. **Log in.** Resolves the LPM.dev Registry bearer token through the standard LPM CLI session. It writes the token to a temporary file and calls `swift package-registry login --token-file <path> --no-confirm`. On Unix, the file mode is `0600`. LPM CLI removes the file after SPM exits, so the bearer does not appear in process arguments. This step runs only for HTTPS because SPM refuses to send authentication over HTTP. If no token is found, this step warns and is skipped. Setup can finish, but protected Swift package requests return `401` until you run `lpm login`.
3. **Install and verify the signing certificate.** Downloads the CMS signing cert from `<registry-url>/api/swift-registry/certificate` with a bounded response reader, parses exactly one complete DER X.509 object, and compares its bytes with `~/.swiftpm/security/trusted-root-certs/lpm.der`. Missing, malformed, trailing-data, stale, or mismatched local bytes are atomically repaired; malformed or oversized Registry responses abort.
4. **Configure the SPM signing trust policy.** Writes `~/.swiftpm/configuration/registries.json` with strict default signing actions (`"error"`). It sets `security.registryOverrides["lpm.dev"].signing.onUntrustedCertificate` to `"silentAllow"` for the hosted Registry. See [Trust model](/docs/packages/swift-package-registry#trust-model) for the rationale.

Fresh configuration includes the required `version` and `registries` fields. LPM CLI migrates the obsolete scope signing action to the configured Registry hostname. It preserves unrelated registry mappings and authentication configuration.

The configuration operation is idempotent. LPM CLI retains matching scope, certificate, and trust configuration without a rewrite. It repairs stale or partial configuration with atomic file writes.

Automatic setup skips SPM login when no credential exists. If a credential exists, a refresh or login failure stops the install. A rejected refresh-backed bearer causes one session refresh and one login retry.
Automatic setup skips SPM login for Free releases and when no credential exists. If a credential exists, a refresh or login failure stops the install. A rejected refresh-backed bearer causes one session refresh and one login retry.

The existing `~/.swiftpm/configuration/registries.json` file has a 16 MiB limit enforced before JSON parsing. Missing retains the setup command's normal create behavior; an oversized file fails with its path and byte limit instead of being treated as absent or overwritten. See [local configuration size limits](/docs/project-setup#local-configuration-size-limits).

Expand Down Expand Up @@ -81,7 +81,7 @@ Plus the [global flags](/docs/commands#global-flags) — `--json` is documented
## Prerequisites

- `swift` on `PATH` (steps 1 and 2 spawn it). Without Swift installed, `lpm swift-registry` errors with `Is Swift installed?` and exits.
- An LPM CLI session (`lpm login`). LPM.dev Registry requires a valid token for all Swift package resolution, including packages that would otherwise be public.
- An LPM CLI session (`lpm login`) for Private, Pool, or Marketplace access. Free releases need no session.

## See also

Expand Down
11 changes: 11 additions & 0 deletions content/docs/registries.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -203,13 +203,24 @@ If you point `certfile=` or `keyfile=` directly at a `.p12`/`.pfx` file, LPM CLI
LPM.dev Registry is a registry **plus** an auth and monetization layer. Use it when:

- You want **private packages** without standing up your own registry. Every published package starts private — only the publisher can install it. (Same shape as npm private packages.)
- You publish a **Free** package that anyone can install without an account or subscription.
- You publish under your scope and want to flip a package to **pool** distribution. Metadata becomes public, but installs are gated to pool subscribers — you earn a share of the pool's revenue.
- You publish a paid package via **marketplace** distribution. Installs require a license purchase.

Setting `distribution` is a per-package opt-in on the publisher's side. As an installer, you simply `lpm install @lpm.dev/owner.package` — LPM CLI handles the auth, license, and download through LPM.dev Registry.

If you're not publishing, ignore LPM.dev Registry entirely — LPM CLI is a strict superset of npm-the-client and will never send your `react` install through it.

## Free packages on LPM.dev Registry

```bash
lpm install @lpm.dev/owner.free-package
```

Free releases need no login. A stale token does not prevent a Free download. Private, Pool, and Marketplace dependencies still require their own access.

When a publisher changes a private package to public distribution, only the latest eligible release and future releases enter review. Earlier private history stays hidden. See [Free distribution](/docs/packages/free-distribution).

## Private packages on LPM.dev Registry

```bash
Expand Down
Loading