LPM-cli

Project health

How lpm doctor structures its checks — pass / warn / fail, parallel network probes, and the auto-fix loop.

lpm doctor is a structured environment check. Each check produces a (name, severity, detail) row; the run finishes with a summary and an exit code (0 if every fail is green, 1 otherwise). This page covers the design — what severity levels mean, how --fix decides what to repair, and how the parallel probe layer keeps a full doctor run under a second on a healthy project.

For the CLI flags, see lpm doctor.

Severity model

Three levels:

SeverityMeaningAffects exit code?
pass (green)The check succeededNo
warn (yellow)Suboptimal but not broken — e.g., outdated tool, expired-but-renewable certNo
fail (red)Broken — e.g., missing required dep, unreachable registry, corrupted store entryYes (exit 1)

A warn is informational — lpm doctor exits 0 even if every check warns. A fail exits 1, which is what CI gates on.

Fast vs full run

By default, lpm doctor runs a fast local-only preset — no network round-trips, no subprocess spawns. The full check set runs under --all.

Under --all, two infrastructure checks run concurrently at the start of the doctor run:

  • Registry healthclient.health_check() against the configured registry URL.
  • Auth checkclient.whoami() if a token exists in the keychain.

Both are network round-trips. Running them in parallel via tokio::join! keeps the worst case to a single round-trip rather than two.

After those two land, the rest of the checks run inline (they're filesystem-bound and fast).

Check inventory (representative)

The authoritative live catalog is lpm doctor list (or --json for machine-readable). Highlights:

GroupChecks
RegistryReachable from this network? Latency reasonable?
AuthToken present? Token valid (via whoami)? Expiry within warning threshold?
RuntimeManaged runtime detected? Detected version installed? PATH includes the right bin/?
Project statepackage.json present and parseable? lpm.lock matches package.json? node_modules/ matches lockfile?
Store~/.lpm/store/ exists and accessible? Lockfile-referenced entries present? Any integrity drift?
SandboxSeatbelt available (macOS) or landlock available (Linux)?
Local HTTPSIf lpm.json > https: true or a project cert exists — CA installed? Cert valid?
ToolsIf lpm.json > tools declares pins — those plugin versions present?
TypeScriptFor each tsconfig.json in the workspace, can tsc be resolved? Healthy when the project-local node_modules/.bin/tsc exists. Warns when only a system-PATH tsc is reachable (editor and CI may diverge). Fails when tsc is not reachable at all.

Each check produces one Check row. Use --json to get the full structured set (every check ID, severity, detail, remediation hint).

Auto-fix mode

lpm doctor --fix              # prompt before each remediation
lpm doctor --fix -y           # skip prompts (CI-friendly)
lpm doctor -y                 # implies --fix
lpm doctor --all --fix        # full sweep + repair (pair --all with --fix to repair every catalog row)

--fix only repairs what was actually checked — running --fix without --all cannot fix rows that the fast preset never ran.

For each fail (and some warns), the remediator either has a known fix or doesn't. Examples of fixable checks:

Check failFix action
Detected managed runtime not installedRun lpm use node@<version> or lpm use bun@<version>
node_modules/ doesn't match lockfileRun lpm install
Local CA not installed in trust storeRun lpm cert trust
Store integrity issueRun lpm store verify --fix
Project formatting driftedRun lpm fmt
Plugin version pinned but not presentRun lpm plugin update <name>

Examples of unfixable checks:

Check failWhy unfixable
Registry unreachableNetwork problem — outside doctor's scope
Token expiredUser has to log in (lpm login) — interactive
Sandbox unavailable on this OSOS-level limitation; nothing doctor can install
TypeScript not installedDoctor doesn't auto-install random packages — lpm install -D typescript is the user's call

Unfixable failures are reported with the recommended next step but no auto-action.

lpm doctor vs lpm health

lpm doctor          # project + environment health (this page)
lpm health          # registry connectivity check (different command)
lpm doctorlpm health
ScopeProject + environmentJust the registry
Reads package.json?YesNo
Hits the network?Only under --all (1–2 calls); default fast preset is local-onlyYes (1 call)
Auto-fix?Yes (--fix)No
Use case"Is my project in a good state?""Is the registry reachable from this CI runner?"

lpm health is the lighter-weight CI smoke test — no project context needed.

JSON output

lpm doctor --json

Structured array of check results:

{
  "success": true,
  "mode": "fast",
  "no_failures": false,
  "clean": false,
  "has_warnings": false,
  "passed": 2,
  "failed": 1,
  "warnings": 0,
  "checks": [
    { "code": "registry_reachable", "check": "Registry", "passed": true, "severity": "pass", "detail": "lpm.dev OK (87ms)" },
    { "code": "node_managed_match", "check": "Node version", "passed": true, "severity": "pass", "detail": "22.12.0 from lpm.json" },
    { "code": "deps_sync_drift", "check": "Dependencies", "passed": false, "severity": "fail", "detail": "drifted from lpm.lock — run `lpm install`" }
  ],
  "fixes_applied": ["lpm install"]
}

Top-level fields:

FieldMeaning
mode"fast" (default, local-only) or "all" (under --all)
no_failurestrue when every check passed (warnings don't break this)
has_warningstrue when at least one check reported warn
cleanno_failures && !has_warnings — the "everything green" shorthand
passed / failed / warningsPer-severity counts
fixes_appliedArray of remediation actions that ran under --fix; empty when --fix wasn't passed

Full envelope shape (per-check fields) is documented on the lpm doctor page. Useful for CI dashboards or agents that want to dispatch on specific failures rather than parse human output.

When to run

  • In CI: as a pre-test step. Fast, catches "the lockfile is stale because the PR forgot to commit it" before the test suite spends 10 minutes failing for a downstream reason.
  • After upgrading LPM: confirms nothing in the new version broke your local state.
  • When something's wrong and you don't know what: doctor's broad-strokes inventory often surfaces it.
  • In onboarding scripts: bundle lpm install && lpm doctor --fix -y && lpm dev for a "clone-to-running" experience.

See also