Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
a68c156
Label LPM CLI's byte sizes in binary units
tolgaergin Oct 11, 2026
677b380
Refresh CLI output documentation dates
tolgaergin Oct 11, 2026
f443aa4
Show an exact size as a whole number in the store clean example
tolgaergin Oct 12, 2026
bd9833e
chore: update content dates
tolgaergin Oct 12, 2026
82850b1
docs: whoami's storage overage states, and the lpm.dev tarball check
tolgaergin Oct 12, 2026
43e4cde
chore: update content dates
tolgaergin Oct 12, 2026
31aad0c
docs: whoami's storage states as the registry decides them, and lpm.d…
tolgaergin Oct 12, 2026
8b97992
chore: update content dates
tolgaergin Oct 12, 2026
27402dd
docs: whoami's exempt storage and refusals, the provenance reserve, t…
tolgaergin Oct 13, 2026
b74cba6
chore: update content dates
tolgaergin Oct 13, 2026
4a7041e
docs: lpm.dev stops every target on any refusal it keeps, release dry…
tolgaergin Oct 13, 2026
b48df97
chore: update content dates
tolgaergin Oct 13, 2026
4e3383d
docs: what stops every target, the second factor settled first, relea…
tolgaergin Oct 13, 2026
d1f46a9
chore: update content dates
tolgaergin Oct 13, 2026
744375a
docs: split the publish, release and login paragraphs on LPM.dev Regi…
tolgaergin Oct 13, 2026
36574d9
chore: update content dates
tolgaergin Oct 13, 2026
597fd6f
docs(publish): name every derived artifact storage counts, and the se…
tolgaergin Oct 13, 2026
c8af4f3
chore: update content dates
tolgaergin Oct 13, 2026
d91f244
docs: rewrite the storage, publish and release passages in plain English
tolgaergin Oct 13, 2026
3601875
chore: update content dates
tolgaergin Oct 13, 2026
ced38ea
Merge remote-tracking branch 'origin/main' into merge/binary-units
tolgaergin Oct 16, 2026
20febfd
chore: update content dates
tolgaergin Oct 16, 2026
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
22 changes: 22 additions & 0 deletions content/docs/infra/login.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,28 @@ lpm whoami --json

The command checks the selected LPM-compatible registry account. Output includes plan, MFA, Pool access, usage, scopes, credential sources, expiry warnings, and storage health.

The output rounds usage past a limit up, so that it shows as past the limit.

On Hobby, the tarballs of packages whose sales exempt them do not count toward the limit. The content that the registry derives from those packages still counts: READMEs, API docs, LLM context, skill content, and for a Swift package, its source archive, raw `Package.swift`, and manifest bundle. The output shows the storage that the limit counts, and shows the exempt tarballs on a separate line.

Past the storage limit, the output says what publishing does, as the registry reports it:

| Report | What publishing does |
| --- | --- |
| Billed | LPM.dev bills storage past the included size per GiB a month, rounded up. The output also says this at the limit, where the next publish starts the billing. |
| Paused | Billing is not active, so the registry refuses publishes past the limit until billing is active again. While Stripe tries a failed payment again, storage that is already past the limit is still billed. It is not billed while the subscription is paused or after it ended. Past the limit, the output says which of these applies, if the registry reports it. |
| Blocked | Nothing bills storage past the limit, so the registry refuses publishes to your personal scope past it. On Hobby, this continues until you upgrade, or delete enough storage to go below the limit. On a Pro plan without a subscription, which staff can grant, this continues while the storage stays past the limit. |

At the storage limit, any publish goes past it. The output says so where the registry refuses publishes. At or past the private-package limit, the output says that the registry refuses new private packages in your personal scope.

Some registries do not report what publishing does past the limit, or the storage that the limit counts. The output then compares the whole storage, exempt tarballs included. On Hobby, at or past the limit, the output says that this registry refuses publishes to your personal scope. Packages whose sales exempt them are the exception. Every LPM.dev Registry refuses Hobby storage past its limit. For other plans, the output says only that the storage is past the limit.

JSON output reports what the registry sent. A field is `null` if the registry does not send it:

- `storage_overage`: what publishing does past the limit
- `storage_excess_billed`: whether storage already past the limit is billed meanwhile
- `usage.counted_storage_bytes`: the storage the limit counts

Human output masks the email address. JSON includes the full address.

The third-party registry list reports credential availability; it does not test each credential with its provider.
Expand Down
2 changes: 1 addition & 1 deletion content/docs/infra/store.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ lpm store clean --json
{
"success": true,
"removed_bytes": 1048576,
"removed": "1.0 MB",
"removed": "1 MiB",
"path": "/Users/you/.lpm/store/v1",
"v1_path": "/Users/you/.lpm/store/v1",
"v2_path": "/Users/you/.lpm/store/v2",
Expand Down
32 changes: 31 additions & 1 deletion content/docs/packages/publish.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,37 @@ Run [`lpm install`](/docs/packages/install) before publication. Missing bundles,
| Encoded archive path | 32 KiB |
| Path components, including `package/` | 256 |

The `package/` prefix leaves 255 components for a project-relative path. Target-specific rewrites and bundled dependencies use the same limits. LPM.dev Registry accepts uploads up to 100 MiB. Other registries can impose smaller limits.
The `package/` prefix leaves 255 components for a project-relative path. Target-specific rewrites and bundled dependencies use the same limits. Other registries can impose smaller limits.

LPM.dev Registry accepts compressed tarballs up to 100 MiB. It accepts publish requests up to 150 MiB, which hold the tarball in base64 with the metadata of the package. If a publish includes LPM.dev Registry, LPM CLI refuses a larger tarball before it publishes to any target. A `--provenance` publish adds its Sigstore bundle to the request two times, about 10 KB each. As a result, LPM CLI keeps 1 MiB of the limit free for it.

## When LPM.dev Registry refuses a publish

A publish to LPM.dev Registry and another target first asks LPM.dev Registry, and sends the size of the tarball. If LPM.dev Registry refuses the publish for good, for permission, payment, or size (HTTP 402, 403, or 413), the publish stops before any target publishes. These refusals are for:

- The storage, private-package limit, or billing of the account
- The 2FA rule or IP allowlist of an organization
- A scope that the account does not own
- The size of the tarball
- The permission of the token

Each target handles other answers at its own upload. One of these answers is a version that LPM.dev Registry already has, for example after a partial publish. LPM.dev Registry gives the `VERSION_EXISTS` code, or an older LPM.dev Registry gives only its message. The LPM.dev target then reports that answer and does not upload. The other targets publish.

Each target also handles these answers at its own upload:

- A request that LPM.dev Registry cannot read
- An unknown package
- A rate limit
- A server error
- An answer that LPM CLI cannot read

After a rate limit, a timeout, or a server error, LPM CLI tries the request again first.

Before any target publishes, the same publish then completes the second factor of LPM.dev Registry, unless LPM.dev Registry already has the version. If 2FA is on, it asks for the code. With `--json` and no `--otp`, it publishes to no target. A malformed `--otp`, or a token that LPM.dev Registry refuses, also stops it at this point.

If LPM CLI cannot read the account, for example while LPM.dev Registry is unavailable, the other targets still publish. The LPM.dev target tries again and reports its own result.

This first question counts the tarball. At the upload, LPM.dev Registry also counts the content that it derives from the tarball: the README, skill content, and for a Swift package, its source archive, raw `Package.swift`, and manifest bundle. As a result, LPM.dev Registry can still refuse a publish at its upload if the publish is within that much of the limit. API docs and LLM context, which it derives later, also count toward storage. `--dry-run` asks the same question and fails on any refusal.

## Credentials and OTP

Expand Down
6 changes: 6 additions & 0 deletions content/docs/packages/release.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,12 @@ lpm release publish --all --lpm --otp 123456 --yes

For LPM.dev Registry, `--otp` supplies the same six-digit authenticator code to each package. Use a fresh code before it expires.

Members publish one at a time. The release prepares and examines each member when it reaches that member. If a member is refused before or at its upload, the release stops after the members that already published. This applies to the size of the member, a secret that its files hold, and the storage of LPM.dev Registry.

If LPM.dev Registry refuses a member in its preflight, the release stops. The error follows the status of the answer, as for any failed request. In `--json` output, its `error_code` is `auth_required`, `forbidden`, `not_found`, `rate_limited`, or `http`, with the message from LPM.dev Registry. The release skips a version that LPM.dev Registry already has. LPM.dev Registry says so with the `VERSION_EXISTS` code, or an older LPM.dev Registry says so with its message.

`--dry-run` prepares every member and examines the version on each target. It does not upload. It does not ask LPM.dev Registry about storage or the private-package limit, which the upload of each member adds to. As a result, a release that passes a dry run can still stop before it is complete.

### Lifecycle scripts

Publishing can run these scripts from each selected member:
Expand Down
2 changes: 1 addition & 1 deletion content/docs/reference/exit-codes.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ A failed operation does not always emit the shared error envelope:
| [lpm exec](/docs/dev/exec), [lpm dlx](/docs/dev/dlx), and direct source-file execution | Child I/O passes through. `--json` does not add a CLI result envelope. |
| [lpm audit](/docs/packages/audit), [lpm tidy](/docs/packages/tidy), and [lpm doctor](/docs/infra/doctor) | Command report plus a status that reflects the selected failure conditions. |

Tool results omit successful child logs and truncate included failed streams at 10 MB each.
Tool results omit successful child logs and truncate included failed streams at 10 MiB each.
An `exit_code: null` with an `error` means the member could not start or prepare its tool.

A command can complete its checks but report findings. For example, doctor can return a completed report with `success: true` and exit `1`.
Expand Down
2 changes: 1 addition & 1 deletion content/docs/reference/terminal-output.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ JSON serialization preserves the semantic values of included strings. It escapes
It does not remove terminal commands from those strings.

This does not guarantee a complete copy of child output. A command can omit successful logs or truncate captured failures.
For example, workspace tool results include failed output with a 10 MB limit per stream.
For example, workspace tool results include failed output with a 10 MiB limit per stream.

Parse JSON before you use its fields. If your program later displays a parsed string in a terminal, sanitize that string at display time.

Expand Down
8 changes: 4 additions & 4 deletions lib/generated/content-dates.json
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@
},
"infra/store.mdx": {
"published": "2026-05-01T09:47:04+01:00",
"modified": "2026-09-20T03:12:34+01:00"
"modified": "2026-10-12T13:47:31+01:00"
},
"infra/token-rotate.mdx": {
"published": "2026-06-16T23:33:51+01:00",
Expand Down Expand Up @@ -353,7 +353,7 @@
},
"packages/publish.mdx": {
"published": "2026-05-01T09:47:04+01:00",
"modified": "2026-09-18T23:56:31+01:00"
"modified": "2026-10-13T21:58:31+01:00"
},
"packages/quality.mdx": {
"published": "2026-05-01T09:47:04+01:00",
Expand All @@ -369,7 +369,7 @@
},
"packages/release.mdx": {
"published": "2026-07-03T10:46:26+01:00",
"modified": "2026-09-17T21:19:46+01:00"
"modified": "2026-10-13T21:58:31+01:00"
},
"packages/remove.mdx": {
"published": "2026-05-01T09:47:04+01:00",
Expand Down Expand Up @@ -501,7 +501,7 @@
},
"reference/terminal-output.mdx": {
"published": "2026-07-22T19:51:43+01:00",
"modified": "2026-09-20T19:20:27+01:00"
"modified": "2026-10-11T15:38:30+01:00"
},
"registries.mdx": {
"published": "2026-05-01T13:51:26+01:00",
Expand Down