LPM CLI

lpm cache

Manage ephemeral caches and prune the global package store.

lpm cache <action>

lpm cache covers two adjacent concerns: ephemeral caches under ~/.lpm/cache/ (registry metadata, task results, dlx tarballs) and the global package store at ~/.lpm/store/.

Examples

lpm cache path                          # print ~/.lpm/cache/
lpm cache path metadata                 # print ~/.lpm/cache/metadata/

lpm cache clean                         # wipe metadata + tasks + dlx
lpm cache clean metadata                # only wipe registry metadata
lpm cache clean tasks                   # only wipe task-runner cache
lpm cache clean dlx                     # only wipe dlx tarball cache

lpm cache status                        # local task cache usage + remote status
lpm cache status --json                 # structured status for CI

lpm cache prune                         # preview orphan store entries (dry-run)
lpm cache prune --apply                 # actually remove orphans
lpm cache prune --max-age 30d --apply   # only entries last touched > 30d ago
lpm cache prune --project ./my-app      # manual repair: walk one project only

Actions

ActionEffect
pathPrint the cache root (~/.lpm/cache/) or one of its subcategories
cleanWipe ephemeral caches (~/.lpm/cache/). lpm cache clear is an alias.
statusReport local task-cache usage and hosted remote-cache status for the current project
pruneReference-aware orphan removal from the global store (~/.lpm/store/) plus a sweep of deferred global-install tombstones

clean accepts an optional subcategory (metadata, tasks, dlx); without one, all three are wiped. clean never touches the global package store — for that, use prune.

Status

lpm cache status reports the local task-cache path and size. If the current project has lpm.json > remoteCache.enabled, it also calls the hosted cache status endpoint and reports the remote status, usage, and quota when the server returns them.

Remote status failures do not make lpm cache status fail; the JSON envelope includes remote.error so CI can decide whether to warn or ignore.

Prune

lpm cache prune walks the global store and removes entries no project still references, then sweeps any deferred global-install tombstones left behind by lpm uninstall -g. Default is dry-run; pass --apply to mutate. Human output ends with an elapsed summary; --json keeps the machine-readable report shape and includes success.

The tombstone sweep runs even when the orphan walk is skipped (registry missing or corrupt — see Safety rails), so lpm uninstall -g's deferred cleanup always has a way to reach disk.

If the project registry is corrupt, prune disables only the project-reachability walk. It still plans or applies crash recovery and age-based eviction for compatibility islands and native build artifacts, cleans their orphaned lock files, and sweeps global-install tombstones. In JSON mode, registry_corrupt: true and registry_corrupt_reason carry the registry problem; tombstone inspection and sweep failures are reported separately.

How it decides what to keep

LPM CLI tracks every project it has installed into in a registry at ~/.lpm/known-projects.json. For each registered project, prune walks the project's node_modules/ symlinks back into ~/.lpm/store/v2/links/<graph-key>/, then BFS through each link entry's sidecar metadata to mark every reachable graph-key. Anything not marked is an orphan. Object directories under ~/.lpm/store/v2/objects/ are pruned the same way — by collecting every surviving link entry's object reference and removing the rest. On macOS, cached compatibility islands under ~/.lpm/store/v2/compat/ are pruned by crash recovery and LRU age: incomplete islands are eligible immediately, and complete islands are eligible only when their last-used sentinel is older than --max-age.

Native lifecycle-build artifacts under ~/.lpm/store/v2/builds/ use the same crash-recovery and LRU rule on macOS and Linux. An incomplete publication is eligible immediately. A complete artifact is kept unless its last-used sentinel is older than --max-age. This cleanup is independent of project reachability, so it remains safe and active when the project registry is missing or corrupt. --apply also removes advisory build-key lock files that no longer have an artifact and graph-entry lock files whose link entry was removed.

Stale registry entries (projects that have moved or been deleted) are dropped silently during the walk. The --max-age filter operates on each link entry's last_referenced_at timestamp (recorded in the entry's sidecar at first population, refreshed by lpm install cache hits) — not on the project registry's last_seen, which is set at install-time only.

Manual repair: --project <path>

When the registry is missing, corrupted, or doesn't reflect actual machine state (after a restore, after copying ~/.lpm/ between machines, etc.), pass --project <path> to walk only that project's lockfile + node_modules/ for roots. The registry is ignored.

This mode is for scripted cleanup of a single project's footprint. Default mode is safer when you have multiple projects on the machine--project only sees the one you point it at, so any link entry referenced by another project would look like an orphan.

Safety rails

  • Dry-run by default. No deletions without --apply.
  • Reachability-degraded mode. If the registry is missing, corrupt, or unreadable AND no --project <path> is supplied, prune cannot identify link/object orphans safely (without trustworthy roots, every link entry would look unreachable). --apply skips only link/object orphan removal. Reachability-independent compatibility-island and native-build-artifact cleanup, orphan lock cleanup, and the tombstone sweep still run. LPM CLI prints a warning naming the cause; for corrupt registries it includes the parser's reason ("not valid JSON" / "unknown schema version" / I/O details) so you can repair the file or delete it for a clean rebuild.
  • Canonicalized paths. The registry stores fully resolved absolute paths, so symlink-cwd quirks don't accumulate aliased entries.
  • Atomic registry rewrites. Updates go through <path>.tmp.<pid> → rename. No partial-write corruption.
  • In-flight installs are respected. Prune coordinates with concurrent lpm install, lpm audit, and lpm query invocations through the store reader/writer lock — dry-run takes the shared half, --apply takes the exclusive half. See lpm store — Locking model.

Flags

FlagApplies toEffect
--applypruneActually remove orphans + sweep tombstones (default is dry-run)
--max-age <DUR>pruneOnly prune entries last touched older than this. Accepts <N>d (days) or <N>h (hours) — nothing else
--project <PATH>pruneManual repair: walk only this project's roots, ignore the registry

Plus the global flags.

JSON output

lpm cache status --json

lpm cache prune --json            # dry-run report
lpm cache prune --apply --json    # post-apply report (same shape, mutations recorded)

status --json emits:

FieldMeaning
local.path / local.bytes / local.sizeLocal task-cache location and usage
remote.enabled / remote.statusHosted cache configuration and server status
remote.usage_bytes / remote.limit_bytesHosted usage and included quota when the server returns them
remote.errorStatus lookup error, if any

prune --json reports both the orphan walk and the tombstone sweep:

FieldMeaning
successfalse when prune could not complete every requested inspection or cleanup step
appliedtrue when --apply was passed
projects_walked / registry_entries_droppedProject-registry coverage stats
link_entries_total / _reachable / _orphaned[]Link-entry walk results; _orphaned[] is a list of paths
object_entries_total / _reachable / _orphaned[]Object-entry walk results
compat_islands_total / _orphaned[]Cached compatibility-island results; _orphaned[] lists incomplete or stale LRU islands
build_artifacts_total / _orphaned[]Native lifecycle-build artifact results; _orphaned[] lists incomplete or stale LRU artifacts
bytes_freed_or_eligibleBytes the orphan walk would free (dry-run) or did free (apply)
registry_missing / registry_corrupt / registry_corrupt_reasonReachability-degraded flags — when either is true, link/object orphan arrays are empty because that walk was skipped; compatibility-island, native-build-artifact, lock, and tombstone cleanup still operate independently
tombstones_pending / _swept / _retained[] / tombstone_bytes_freedTombstone sweep results — _swept and _bytes_freed are zero on dry-run

lpm cache clean emits a parallel {success, cleaned[], total_bytes_freed, total_freed} envelope per subcategory.

See also