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 onlyActions
| Action | Effect |
|---|---|
path | Print the cache root (~/.lpm/cache/) or one of its subcategories |
clean | Wipe ephemeral caches (~/.lpm/cache/). lpm cache clear is an alias. |
status | Report local task-cache usage and hosted remote-cache status for the current project |
prune | Reference-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 degrades to tombstone-only mode and still exits zero unless tombstone inspection or the --apply tombstone sweep fails. In JSON mode, registry_corrupt: true and registry_corrupt_reason carry the registry problem; success becomes false only for tombstone_count_error or tombstone_sweep_error.
How it decides what to keep
LPM 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.
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. - Tombstone-only degraded mode. If the registry is missing, corrupt, or unreadable AND no
--project <path>is supplied, prune cannot identify orphans safely (without trustworthy roots, every link entry would look unreachable).--applyskips orphan removal in this case, runs the tombstone sweep regardless, and prints a warning naming the cause. For corrupt registries the warning 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, andlpm queryinvocations through the store reader/writer lock — dry-run takes the shared half,--applytakes the exclusive half. Seelpm store— Locking model.
Flags
| Flag | Applies to | Effect |
|---|---|---|
--apply | prune | Actually remove orphans + sweep tombstones (default is dry-run) |
--max-age <DUR> | prune | Only prune entries last touched older than this. Accepts <N>d (days) or <N>h (hours) — nothing else |
--project <PATH> | prune | Manual 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:
| Field | Meaning |
|---|---|
local.path / local.bytes / local.size | Local task-cache location and usage |
remote.enabled / remote.status | Hosted cache configuration and server status |
remote.usage_bytes / remote.limit_bytes | Hosted usage and included quota when the server returns them |
remote.error | Status lookup error, if any |
prune --json reports both the orphan walk and the tombstone sweep:
| Field | Meaning |
|---|---|
success | false when prune could not complete every requested inspection or cleanup step |
applied | true when --apply was passed |
projects_walked / registry_entries_dropped | Project-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 |
bytes_freed_or_eligible | Bytes the orphan walk would free (dry-run) or did free (apply) |
registry_missing / registry_corrupt / registry_corrupt_reason | Degraded-mode flags — when either is true, orphan paths arrays are empty (walk was skipped) and tombstones are the only mutation reported |
tombstones_pending / _swept / _retained[] / tombstone_bytes_freed | Tombstone 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
- Content-addressable store — design overview, on-disk layout
lpm store— integrity checks, store path, blunt full wipelpm doctor— surfaces store-size hints alongside other checks