LPM CLI

lpm stage

Stage npm packages, inspect their contents, and approve or reject publication.

Use lpm stage to review an npm package upload before it becomes installable.

lpm stage <COMMAND>
lpm stage publish [OPTIONS]
lpm stage list [OPTIONS] [PACKAGE]
lpm stage view [OPTIONS] <STAGE_ID>
lpm stage download [OPTIONS] <STAGE_ID>
lpm stage approve [OPTIONS] <STAGE_ID>
lpm stage reject [OPTIONS] <STAGE_ID>
CommandPurpose
publishPrepare the current package and upload it to staging.
listList staged versions visible to your token.
viewShow one staged entry.
downloadSave the staged tarball for inspection.
approvePromote the staged version to the live registry.
rejectDiscard the staged version.

Staging uses the npm staging API. It supports npm and compatible staging registries. For direct publication, use lpm publish.

Quickstart

From the package directory:

lpm stage publish --dry-run --ignore-scripts
lpm stage publish --tag next --yes
lpm stage list
lpm stage view <STAGE_ID>
lpm stage download <STAGE_ID>
lpm stage approve <STAGE_ID> --otp 123456

The package must already exist in the registry before a real staging upload. The staged version must not already be published.

Examples

# Stage from CI with lifecycle scripts
lpm stage publish --yes --json

# Stage without scripts or configured provenance
lpm stage publish --ignore-scripts --no-provenance --yes --json

# Inspect one package's staged versions
lpm stage list @acme/core --json

# Reject a staged version without an authentication prompt
lpm stage reject <STAGE_ID> --otp 123456 --json

# Use a compatible staging registry for this run
lpm stage list --npm-registry https://registry.example.com/npm

Registry and OTP flags go after the subcommand. The global --registry flag selects LPM.dev Registry and is rejected by stage commands.

Configure staging with lpm.json

Staging reads the npm section of lpm.json:

{
  "publish": {
    "npm": {
      "name": "@acme/core",
      "access": "public",
      "tag": "next",
      "registry": "https://registry.npmjs.org"
    }
  }
}
# Use the configured npm name, access, tag, and registry
lpm stage publish --yes

# Override the tag and disable configured provenance for one run
lpm stage publish --tag beta --no-provenance --yes
SettingPrecedence
Package namepublish.npm.name → selected manifest name
Access--access → publish.npm.access → public
Dist-tag--tag → publish.npm.tag → implicit latest
Registry--npm-registry → publish.npm.registry → public npm

Registry configuration applies to every subcommand. Invalid lpm.json stops the command before authentication or requests.

publish.registries and the other target sections do not select staging destinations. publish.npm.otpRequired does not apply to staging. Stage publication defers OTP to approval or rejection.

There are no staging configuration fields for script consent or minimum quality. Use --yes, --ignore-scripts, and --min-score for each run.

Prepare a staged version

The selected package needs a valid npm name and semantic version. A manifest with private: true blocks staging. An unscoped package cannot use restricted access.

Staging supports publishConfig.directory, workspace and catalog rewrites, bundled dependencies, and target-name overrides. It validates authored skills and scans the final artifact for secrets.

Staging always computes a local quality score. To require a threshold:

lpm stage publish --min-score 80 --yes

See lpm quality for the score categories. --allow-secrets skips the artifact secret scan, but does not skip skill validation.

Versions and tags

For a real staging upload:

  • The package must already exist in the registry.
  • The version must not already be published.
  • A prerelease needs an explicit --tag or publish.npm.tag.
  • If a higher stable version exists, an implicit latest tag is rejected.

Tags must be valid npm dist-tags. Empty values, whitespace, and version-like tags cause an error.

lpm stage publish --tag next --yes
lpm stage publish --tag legacy --yes

Lifecycle scripts and dry runs

Staging runs prepublishOnly, prepack, and prepare before packing, then postpack after packing. It does not run publish or postpublish.

These four scripts also run during --dry-run. For non-interactive or JSON output, use --yes to authorize scripts or --ignore-scripts to skip them.

lpm stage publish --dry-run --yes --json
lpm stage publish --dry-run --ignore-scripts --json

Scripts use the publish sandbox, including its five-minute timeout and denied outbound network access. Scripts can change project files during a dry run.

A dry run packs, validates, scans, and scores locally. It does not authenticate, check registry versions, generate provenance, or upload. A supplied provenance file still receives local validation. The reported tarball size includes the final name rewrite.

Provenance

Staging uses the publish provenance configuration, including its precedence, path limits, and CI requirements.

lpm stage publish --access public --provenance --yes
lpm stage publish --provenance-file bundle.sigstore --yes
lpm stage publish --no-provenance --yes

Provenance requires effective public access. The three provenance flags are mutually exclusive. A successful dry run does not prove that CI signing will succeed.

Inspect and download

lpm stage list
lpm stage list @acme/core
lpm stage view <STAGE_ID> --json
lpm stage download <STAGE_ID> --json

Stage IDs use UUID form. list without a package shows entries visible to the token. Package filters accept a name or name@*. Other version selectors cause an error.

Lists load pages automatically, up to 10,000 items or 100 pages. Human view output shows the ID, package version, and tag. JSON includes the full entry.

download validates the tarball and its manifest, then saves it in the current directory. It does not extract the archive. It does not compare the archive with a separately fetched registry integrity value.

The usual filename is <name>-<version>-<stage-id>.tgz. Scoped names use a hyphen, such as acme-core. Long names or versions receive a shortened prefix. The stage ID remains intact, and the filename stays within 255 bytes.

Downloads preserve archive bytes, including manifests with a UTF-8 BOM. An existing destination causes an error. There is no output-path or overwrite flag.

Download limitMaximum
Compressed tarball500 MiB
One expanded entry512 MiB
Total expanded entry data1 GiB
Archive entries100,000
Package manifest16 MiB

Publication preparation uses the publish archive limits.

Approve or reject

lpm stage approve <STAGE_ID> --otp 123456 --json
lpm stage reject <STAGE_ID> --otp 123456 --json

Approval makes the staged package installable. Rejection removes the staged entry.

These commands can use interactive OTP or browser authentication. --json disables those prompts. Neither command has a --yes flag. Stage publication itself has no OTP flag.

Authentication

For public npm, stage publication can use npm Trusted Publishing. Otherwise, credentials come from NPM_TOKEN, a stored npm token, or effective .npmrc authentication.

list, view, download, approve, and reject require token authentication. They do not use Trusted Publishing.

For a custom registry, an exact stored registry token takes precedence:

lpm login --login-registry https://registry.example.com/npm --token '<token>'
lpm stage list --npm-registry https://registry.example.com/npm --json

A non-default registry from lpm.json requires that scoped token. With explicit --npm-registry, normal npm credentials remain a fallback when no scoped token exists. Select the intended endpoint before you use this fallback.

Registry URLs require HTTPS, except for HTTP loopback development endpoints. Credentials, queries, and fragments are rejected in registry URLs. See Authentication for token storage.

Recover from failures

Staging stops before scripts or upload if an interrupted local version or release transaction needs recovery. Recover it with the original lpm version or lpm release workflow, then retry staging.

If an upload fails after the request reaches the registry, inspect list and view before retrying. Staging has no local resume record or automatic upload reconciliation.

If a download destination exists, inspect or move that file before another download. If authentication fails, refresh the credential for the selected registry. A custom-registry token must match the full endpoint, including its path.

JSON output

Every command supports global --json and includes success, target: "npm", and the selected registry on success.

CommandAdditional fields
Real publishauth, stageId, duration_ms, registry-response data
publish --dry-runPackage plan fields, tarball_size, and quality
listtotal and an item array in data
viewstageId and the registry entry in data
downloadstageId, path, bytes, and the archive manifest in data
approve, rejectstageId, action, and registry-response data

Failures use the standard JSON error format.

Flags

Publish flags

FlagDescription
--tag <TAG>Override the npm dist-tag. Counts as an explicit tag.
--access <ACCESS>Override access with public or restricted.
--dry-runPrepare locally without authentication, remote checks, or upload.
-y, --yesAccept confirmation and authorize lifecycle scripts.
--ignore-scriptsSkip lifecycle scripts.
--min-score <MIN_SCORE>Required local quality score, from 0 to 100.
--allow-secretsSkip the final-artifact secret scan.
--provenanceRequire generated Sigstore provenance.
--no-provenanceDisable configured provenance.
--provenance-file <PATH>Attach a verified Sigstore bundle.

Other flags

FlagCommandsDescription
--npm-registry <URL>AllOverride the staging registry. Place it after the subcommand.
--otp <OTP>approve, rejectSupply an OTP with the initial request. Use --json to disable authentication prompts.

All commands support --json and the applicable global flags.

See also