Usage
vg bisect <package> <constraint>
What It Does
Where vg why narrates every version change for a dependency, vg bisect answers one targeted question: when did we cross this line? It reads your lockfile's history — offline, without checking out any commit — and finds the commit that first reached the constraint, with the version before and after, the author, and the date.
<constraint> is a version or a semver range. A bare version means "reached or surpassed" — vg bisect lodash 4.17.21 is the same as vg bisect lodash '>=4.17.21'. Pass an explicit range (^18, >=2 <3) when you need one.
Example
vg bisect lodash 4.17.21
If the dependency reached the line, the run shows the crossing commit and the version before and after. If it never did, vg bisect says so and shows the latest version in history — a clear "the fix is still not in" answer. A later flip, such as a downgrade that re-introduced the old version, is listed too.
Gate CI With --assert
vg bisect lodash 4.17.21 --assert
With --assert, the command exits non-zero when the current version does not satisfy the constraint, so a pipeline step can block a merge until the fix is adopted. Exit codes: 0 when the query resolves, 2 when --assert finds the constraint unsatisfied, 3 when the package has no version history, and 5 for an invalid version or range.
Supported Ecosystems
vg bisect works wherever a resolved lockfile is committed: npm / pnpm / yarn, pip / poetry / pipenv, cargo, composer, bundler, go, pub, hex, NuGet, and Maven/Gradle. For Maven/Gradle it reads a resolved gradle.lockfile, or a pom.xml's pinned direct-dependency versions (BOM/dependencyManagement-managed versions aren't resolved). It needs git history, so run it inside a git repository.
JSON Output
vg bisect lodash 4.17.21 --json
Returns the constraint, the current version, whether it is satisfied now, and every crossing as structured JSON for automation.
How It Relates to vg why
vg why shows a dependency's full history; vg bisect pinpoints the single boundary you asked about and can gate CI on it. Both read the same offline lockfile timeline.