Summary
package-lock.json on main contains 9 unresolved `git stash` conflict blocks (27 conflict-marker lines), making it invalid JSON. npm ci from a fresh clone fails.
How it was found
Surfaced during /release prep for v2.6.2. The pre-flight "clean working tree" check passed because the corruption is committed, not a working-tree change — so git status is clean and the bad file sits at HEAD.
Root cause
Introduced by commit 512840f (PR #716, fix #711). A git stash pop during that branch's prep left conflict markers in package-lock.json that were committed. Each block is the same shape — a disagreement over whether a transitive package carries "dev": true:
```
<<<<<<< Updated upstream
Stashed changes
```
Affected packages: cross-spawn, debug, fast-deep-equal, isexe, ms, path-key, shebang-command (+2).
Why CI/tests didn't catch it
- npm does not publish
package-lock.json to the tarball, so npm consumers were unaffected.
npm install/tsc/vitest tolerate the existing node_modules; only npm ci (fresh clone) parses the lockfile strictly.
Fix
Regenerate the lockfile via npm install --package-lock-only, which recomputes the dependency tree deterministically and drops the spurious "dev": true flags (these packages are production-reachable). Result: 0 conflict markers, valid JSON, npm ci --dry-run passes.
Follow-up (separate)
Consider an npm ci-on-a-fresh-checkout CI gate (or a lockfile-conflict-marker lint) so a corrupt lockfile can't reach main again.
Summary
package-lock.jsononmaincontains 9 unresolved `git stash` conflict blocks (27 conflict-marker lines), making it invalid JSON.npm cifrom a fresh clone fails.How it was found
Surfaced during
/releaseprep for v2.6.2. The pre-flight "clean working tree" check passed because the corruption is committed, not a working-tree change — sogit statusis clean and the bad file sits at HEAD.Root cause
Introduced by commit
512840f(PR #716, fix #711). Agit stash popduring that branch's prep left conflict markers inpackage-lock.jsonthat were committed. Each block is the same shape — a disagreement over whether a transitive package carries"dev": true:```
<<<<<<< Updated upstream
Affected packages:
cross-spawn,debug,fast-deep-equal,isexe,ms,path-key,shebang-command(+2).Why CI/tests didn't catch it
package-lock.jsonto the tarball, so npm consumers were unaffected.npm install/tsc/vitesttolerate the existingnode_modules; onlynpm ci(fresh clone) parses the lockfile strictly.Fix
Regenerate the lockfile via
npm install --package-lock-only, which recomputes the dependency tree deterministically and drops the spurious"dev": trueflags (these packages are production-reachable). Result: 0 conflict markers, valid JSON,npm ci --dry-runpasses.Follow-up (separate)
Consider an
npm ci-on-a-fresh-checkout CI gate (or a lockfile-conflict-marker lint) so a corrupt lockfile can't reachmainagain.