LPM CLI

lpm query

Find dependencies by name, behavior, state, or relationship, and use selectors as CI checks.

Find dependency instances that match a selector, or count behavioral tags across your dependency tree.

lpm query [OPTIONS] [SELECTOR]

Quickstart

lpm query '#lodash'
lpm query ':scripts:not(:built)'
lpm query ':critical' --assert-none

Quote selectors so that your shell does not interpret #, >, *, or parentheses.

ModeEffect
lpm query '<selector>'List matching dependency instances.
lpm query --countCount tags across all dependencies.
lpm query '<selector>' --assert-noneExit with code 1 if any dependency matches.
lpm query '<selector>' --format mermaidRender matches and adjacent dependencies as a Mermaid graph.

LPM CLI supports npm, private registries, and the LPM.dev Registry. Query can inspect supported foreign lockfiles and installed packages.

Examples

# Find an exact version, including build metadata
lpm query '#example@1.0.0+build.1'

# Find direct dependencies with network capabilities
lpm query ':root > :network'

# Match both tags
lpm query ':eval:scripts'

# Match either tag
lpm query ':eval,:child-process'

# Inspect full analysis details
lpm query ':network' --json --query-verbose

# Save a diagram for an LPM CLI-managed project
lpm query ':eval' --format mermaid > eval-graph.mmd

For a reusable check, define an uncached task:

lpm.json
{
  "tasks": {
    "deps:gate": {
      "command": "lpm query ':critical' --assert-none",
      "cache": false
    }
  }
}
lpm run deps:gate

There is no dedicated query configuration in lpm.json. command holds the selector and options. cache: false runs the check each time.

For a different one-run policy, invoke the command directly with another selector. An explicit lpm.json task command takes precedence in lpm run.

Selectors

SyntaxMeaning
*All dependency instances.
#nameAll instances of an exact package name.
#name@versionAn exact name and version. Scoped names are supported.
:a:bBoth selectors match.
:a,:bEither selector matches.
:not(:a)The selector does not match.
#parent > #childThe child is a direct dependency of the parent. LPM CLI lockfiles also include resolved peer edges.
:root > :aA direct dependency of the selected project matches :a.
:workspace-root > :aA direct dependency of the owning workspace root matches :a.

> follows dependency edges. It does not select every descendant.

Behavioral tags

These tags describe static analysis results. A capability such as filesystem or network access does not, by itself, establish malicious behavior.

TagMatches packages that
:evalUse eval, Function(), or vm.runInThisContext
:networkMake outbound HTTP / WS connections
:fsUse filesystem APIs
:shellSpawn shells (spawn, exec, execSync)
:child-processUse child_process (any form)
:nativeShip native modules (.node, .wasm)
:cryptoUse cryptographic primitives
:dynamic-requireUse dynamic require() (variable arg)
:envRead process.env
:wsUse WebSockets
:obfuscatedShow signs of code obfuscation
:possible-obfuscationShow possible code obfuscation at moderate confidence
:high-entropyContain high-entropy string blobs
:minifiedShip minified-only source
:telemetryMake telemetry / analytics calls
:url-stringsContain URL string literals
:trivialTiny — measured by AST node count
:protestwareMatch a curated list of known protest-license / sabotage packages
:credential-exfiltrationSend credential-file contents, private-key material, or the complete process environment in a network payload
:encrypted-executionDecrypted bytes reach code evaluation or a file passed to a process launcher
:downloaded-executionA downloaded response reaches code evaluation or a file passed to a process launcher
:destructive-filesystemRecursively remove the home directory, a filesystem root, or current project contents

The :fs tag does not establish access outside the package directory. The :obfuscated tag requires high-confidence signals.

Manifest and state tags

TagMatches
:git-depDeclare a dependency with a git URL
:http-depDeclare a dependency with an insecure HTTP URL
:wildcard-depDeclare a dependency with *, latest, or an empty version
:copyleftDeclare a license expression with a recognized copyleft license
:no-licenseHave no usable license declaration, except private packages
:scriptsA package declares preinstall, install, postinstall, or prepare.
:builtA regular .lpm-built marker exists in the selected package directory.
:vulnerableAdvisory data identifies the installed name and version.
:deprecatedRegistry metadata marks the installed version as deprecated.
:lpmThe name starts with @lpm.dev/.
:npmThe name does not start with @lpm.dev/, including local and private-registry packages.

Dependency protocol tags describe declarations inside a package. They do not describe where that package itself came from.

:no-license also includes declarations such as UNLICENSED, none, proprietary, and SEE LICENSE IN ... for non-private packages.

For exact license inventory and policy checks, use lpm licenses.

A build marker does not prove current approval, a successful security review, or a vulnerability fix. Use lpm trust to inspect approval changes.

Severity selectors

Severity selectors combine these tags with OR:

SelectorTags
:critical:obfuscated, :protestware, :credential-exfiltration, :destructive-filesystem.
:high:eval, :child-process, :shell, :dynamic-require, :encrypted-execution, :downloaded-execution, :scripts, :vulnerable.
:medium:network, :git-dep, :http-dep, :wildcard-dep, :no-license, :native.
:info:fs, :crypto, :env, :ws, :possible-obfuscation, :high-entropy, :telemetry, :trivial, :copyleft, :minified, :url-strings.

:high includes any reported vulnerability and any matching lifecycle-script declaration. It is not a vulnerability-severity threshold.

Project and workspace scope

With a lockfile, query selects the applicable project from the current directory, including nested directories. With an LPM CLI workspace lockfile, queries use the selected member's dependency tree.

For other package managers, query uses the whole inventory from the discovered lockfile. It does not select a separate workspace-member tree.

Without a lockfile, run query from the directory that contains node_modules.

:root and :workspace-root are virtual anchors for >. They are not dependency result rows.

cd packages/web/src
lpm query ':root > :scripts'
lpm query ':workspace-root > :scripts'

With an LPM CLI workspace lockfile, the second command uses the owning root's exact dependency instances. It can inspect root dependencies outside the member's normal tree.

Outside an LPM CLI workspace, both anchors use the selected project. For another package manager, this project is the discovered lockfile directory. If an LPM CLI workspace lockfile lacks a root projection, the workspace-root anchor has no children.

Direct dependencies include optional and development dependencies. Query has no production-only, recursive, or workspace-filter flag.

CI checks and incomplete scans

# Fail when any critical tag matches
lpm query ':critical' --assert-none

# Save matching rows and retain the failing status
lpm query ':eval:scripts' --assert-none --json > dependency-findings.json

Without --assert-none, a completed query exits with code 0, even when packages match. With this flag, matches cause code 1.

Incomplete required analysis, unreadable script state, invalid selectors, and registry failures also produce a nonzero status. An empty match list cannot establish a clean result after those failures.

Behavioral queries require readable package sources, valid package manifests, and complete analysis. Pure identity queries in compact JSON do not require script, build, or advisory state.

If sources are missing, restore the installed tree with lpm install, then rerun the query. Unsupported source syntax or exceeded scan limits require separate review.

For broader reports and severity policies, use lpm audit.

Network requests

Behavioral tags, scripts, and build markers use local files. These requests also need remote data:

RequestRemote data
:vulnerable, :high, or expressions that contain themOSV advisories for non-@lpm.dev names, and LPM.dev Registry advisories for @lpm.dev names.
--countThe same advisory lookups.
--json --query-verboseAdvisory data for the detailed result.
:deprecatedVersion metadata from the current registry route, including .npmrc routes and credentials.

OSV requests include package names and versions from private registries and local sources when their names do not start with @lpm.dev/.

Negating a selector still requires its data. For example, :not(:vulnerable) needs advisory lookups.

Output

JSON and counts

lpm query '#lodash' --json
lpm query ':network' --json --query-verbose
lpm query --count --json

Selector JSON is one array, including when --assert-none fails. Each row contains name, version, and an optional path.

Exact LPM CLI-managed instances also include instanceId. Same-name versions and separate instances remain separate rows.

Detailed JSON adds analysis, hasScripts, isBuilt, and isVulnerable. A live file: or link: dependency can use its source directory as path.

Count JSON is an object with tag counts and total. An empty inventory still returns this object with zero counts.

--count cannot accompany a selector, --assert-none, --format, or --query-verbose.

Mermaid

lpm query ':eval' --format mermaid > eval-graph.mmd
lpm query ':eval' --format mermaid --assert-none

Mermaid output requires an LPM CLI-managed lockfile. It includes matching instances and their adjacent dependency or peer nodes.

Matched nodes receive a highlight. Exact instance labels include a short instance ID. --assert-none also applies to this output.

--json and --format mermaid cannot be combined. For a full graph, use lpm graph.

Flags

Argument or flagEffect
[SELECTOR]Selector expression. Required unless --count is present.
--countCount tags across all dependencies.
--query-verboseInclude full analysis and state in JSON results. Global --verbose also enables this detail.
--assert-noneExit with code 1 when any package matches.
--format <list|mermaid>Select the output format. Default: list.
--jsonEmit result rows or tag counts as JSON.

See global flags for shared options.

See also