LPM CLI

lpm approve-scripts

Review blocked dependency scripts and save approvals for the exact package artifacts you select.

Review dependency scripts blocked during installation, then save permission to run them.

lpm approve-scripts [OPTIONS] [PACKAGE]

Quickstart

# List dependencies that need review
lpm approve-scripts --list

# Review one installed package
lpm approve-scripts esbuild

# Run approved dependency scripts
lpm rebuild

Approval saves trust. It does not execute scripts. Use lpm rebuild after approval.

ModePurpose
No package or mode flagReview the blocked set interactively
[PACKAGE]Select one package, version, or artifact
--listShow the blocked set without changes
--yesApprove every blocked entry only if all entries have a green classification
--dry-runPreview the selected review flow without writes
--globalReview dependencies of globally installed packages

Project review acts on the nearest directory with a package.json, as lpm install does. From a subdirectory, the command prints the directory it chose.

Examples

# Inspect the queue as JSON
lpm approve-scripts --list --json

# Preview one version without changing trust
lpm approve-scripts esbuild@0.25.1 --dry-run --json

# Preview bulk approval of a fully green queue
lpm approve-scripts --yes --dry-run --json

# List global dependencies by the package that installed them
lpm approve-scripts --global --list --group

For a reusable review report, define an uncached task:

lpm.json
{
  "tasks": {
    "deps:scripts": {
      "command": "lpm approve-scripts --list",
      "cache": false
    }
  }
}
lpm run deps:scripts

There are no dedicated approval fields in lpm.json. The task's command holds the flags. cache: false reads current review state each time.

An explicit task command takes precedence over a same-name package script in lpm run.

For a different mode on one run, call lpm approve-scripts directly. Dependency policy and approvals live in package.json.

What enters the review queue

lpm install captures dependencies with blocked preinstall, install, or postinstall scripts.

Other script names, including prepare, prepublishOnly, and uninstall scripts, do not enter this queue. Root-project scripts use the install command's separate lifecycle rules.

The project queue comes from authenticated .lpm/build-state.json. The command filters out approvals that already match the current project policy.

An approval binds the package name, version, integrity, and lifecycle script hash. The hash also covers recognized local JavaScript delegates and their reachable imports.

Temporary advisor approvals also bind the complete script hash. Changed delegated files invalidate those approvals and their cached decisions.

Different artifacts with the same name and version remain separate. Equivalent copies share one review entry. Duplicate entries retain conservative classification and drift information.

Install capture uses the exact installed package files. Missing or invalid manifests fail capture instead of silently removing review entries.

Select an artifact

lpm approve-scripts esbuild
lpm approve-scripts esbuild@0.25.1
lpm approve-scripts 'esbuild@0.25.1#<artifact-id>'

A bare name or version must match one blocked artifact. If it matches several artifacts, the error lists qualified selectors to use.

Copy a complete selector from that error. Different integrity values or script hashes can require separate approvals at one version.

A named package outside the blocked set fails. A package whose current binding already matches also fails with an explanatory message.

Review and authorization

Interactive cards show package identity, lifecycle phases, static classification, and drift information. You can approve, skip, or inspect a package.

When an earlier approval exists, project review can show changed script lines and behavioral tags. Script bodies appear only when they match the recorded binding.

If matching bytes are unavailable, the diff reports that limitation. A classification or registry tag is review evidence, not a guarantee of safe behavior.

A named project approval still asks for confirmation in a human terminal. JSON and noninteractive named approvals skip that selection prompt.

On project review, quitting discards the pending selections. On global review, quitting preserves approvals already written during that session.

Bulk approval

lpm approve-scripts --yes --dry-run

--yes refuses amber, amber-llm, red, and unclassified entries before it writes approvals. Review those packages individually.

If every entry is green, live bulk approval still requires authorization and emits a warning. --yes does not bypass security authorization.

Noninteractive approval

From a user-controlled terminal, authorize the project trust change:

lpm security unlock trust-bulk-approve --project . --ttl 10m

Then select the package without an interactive review prompt:

lpm approve-scripts esbuild --json

The signed grant applies to that project and expires. Managed policy can reject a requested change.

Dry runs retain selector and tier checks. They skip trust writes and provenance fetches. A successful preview does not guarantee authorization for a live write.

Saved approvals and drift

Project approvals use the rich-map form in package.json > lpm > trustedDependencies. Global approvals use ~/.lpm/global/trusted-dependencies.json.

These approvals do not live in lpm.lock. See the trust storage contract.

Bindings can also contain provenance and a hash of approved capabilities. Capability hashes appear when the project requests access beyond its authorized baseline. No approval lets a script write LPM CLI's state in the project's .lpm/ directory, and only an approved readProject: "full" lets it read that state. A sandboxWriteDirs entry inside .lpm or above the project, and a sandboxReadAllow or script-read-allow entry inside .lpm, are rejected. See the project's .lpm directory.

Changed scripts, integrity, or capabilities can invalidate an approval. Review the new artifact before another lpm rebuild.

During live approval, LPM CLI fetches available provenance. Verification failures follow the configured enforcement policy. Missing evidence and transport failures can leave provenance unavailable.

The provenance policy uses LPM_PROVENANCE_ENFORCE, then [sigstore].verify in user configuration, then the default deny.

Weakening verification to warn or off requires separate provenance-unverified authorization. The error supplies the project or global unlock command.

--list and --dry-run do not require that provenance override grant.

Global approvals

lpm approve-scripts --global --list
lpm approve-scripts --global --group
lpm approve-scripts --global esbuild --dry-run --json

Global review combines the captured queues of globally installed packages. Equivalent dependency bindings share a row that lists their installation origins.

--group groups list or interactive output by top-level package. Grouping starts automatically when the queue contains more than 10 entries.

Named global approval skips the package-review prompt. Live trust changes still require global authorization.

If an install root has missing or invalid review state, global listing reports unreadable_origins. Bulk approval refuses an incomplete aggregate.

After live global approval, the output lists the affected top-level packages and their reinstall commands. Global approval does not execute their scripts.

Follow those commands to apply the approvals. Project lpm rebuild has no global mode.

JSON output

lpm approve-scripts --list --json > blocked-scripts.json
lpm approve-scripts esbuild --dry-run --json

Pair --json with --list, --yes, or a package selector. A nonempty interactive queue cannot use JSON mode.

Project reports use schema_version: 3 and include counts, dry_run, and blocked entries. Entries include identity, script hash, phases, classification, and drift data.

version_diff describes changes relative to a previous approval, or is null for a first review. Global entries also include installation origins.

Successful live approvals include follow-up commands when applicable. Dry runs omit these commands because no trust change occurred.

Fix common problems

If review state is missing, unsigned, invalid, or incompatible, run lpm install to capture it again.

If a selector is ambiguous, use an artifact-qualified candidate from the error.

If script bytes no longer match the captured hash, refresh the install and review the new queue.

If package.json changes during review, the command refuses the write. Review the current manifest and retry.

If global listing reports unreadable origins, reinstall those top-level packages before bulk approval.

If script execution later fails on Windows, check sandbox permissions. Approval does not replace administrator setup.

Flags

Flag or argumentEffect
[PACKAGE]Select name, name@version, or name@version#artifact-id.
--yesApprove a fully green blocked set with authorization.
--listList without prompts or trust changes. Conflicts with --yes and a package selector.
--dry-runPreview without writes or provenance fetches. Works with named, bulk, interactive, and global review.
--globalRead global install queues and write global trust.
--groupGroup global list or interactive output. Requires --global; conflicts with --yes and a package selector.
--jsonEmit structured output for a noninteractive mode.

--list --dry-run remains read-only and records dry_run: true. See global flags for shared options.

See also