feat: workspace-scoped lockfile-refresh commands, section rendering fix, and fix coverage count#451
Merged
Conversation
…ve fixes When the parent package's declared range already covers the fixed version of a vulnerable transitive dependency, non-npm package managers can update the lockfile directly without a parent version bump. Previously, fix-commands.ts skipped this case for all non-npm package managers with a message that the fix path was npm-specific. This change replaces that skip with targeted update commands: - pnpm: pnpm update <dep> - yarn: yarn upgrade <dep> - bun: bun update <dep> Closes #450
…registry Extends the transitive remediation scanner to check whether the installed parent package already declares a version range that covers the fixed transitive dependency. Previously this check only ran for npm (via the package-lock graph). For pnpm, yarn, and bun lockfiles the scanner now fetches the installed parent's published manifest from the npm registry and checks whether the parent's declared range for the vulnerable child already allows a safe version. When a match is found, the finding gets recommendedNpmTransitiveRemediation set to update-parent-within-range and fix-commands.ts emits the correct lockfile-refresh command (pnpm update / yarn upgrade / bun update) instead of skipping the finding. Closes #450
Plain pnpm update only runs in the root workspace. For monorepos where a transitive dep is pulled in across multiple importers, --recursive ensures all workspace lockfile entries are refreshed. --no-save prevents pnpm from writing the package to any workspace package.json, which is correct since we are only refreshing a transitive dependency's resolved version.
…ng, add coverage count - Add workspace map builders for npm (package-lock.json), pnpm (pnpm-lock.yaml), and bun (bun.lock) to track which workspaces declare each direct dependency - Read pnpm-workspace.yaml as fallback when package.json has no workspaces field, fixing direct-dependency detection in pnpm monorepos - Emit workspace-scoped lockfile-refresh commands: npm update --workspace=<path>, pnpm -C <path> update --no-save, pnpm update --recursive for multi-workspace - Collect workspace paths from all dependency paths (not just the shortest), ensuring every affected workspace gets the correct scoped command - Move parent-update targets into their own sections (Critical/High severity parent updates within range) to eliminate mixed-table rendering - Fix HTML report to use displayTargetVersion (within current range) instead of raw semver for parent-update targets - Show fix coverage count after the command plan in both terminal and HTML: Running all commands above should fix X of Y findings - Wrap workspace map builders in try-catch so a parse failure never aborts the scan -- workspace scoping is best-effort
…context strings The previous label and context strings were opaque — 'within current range' gave no hint to the developer that a lockfile refresh (not a parent upgrade) is what's needed. Replace with 'lockfile refresh' as the display label and rewrite the reason strings to state plainly that the parent already permits the safe child version.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Extends #450 with workspace awareness and output improvements across all three areas.
Workspace-scoped commands — npm, pnpm, and bun now emit workspace-targeted commands when a lockfile-refresh can fix a transitive vulnerability. For pnpm this means
pnpm -C <path> update --no-save <pkg>for a single workspace orpnpm update --recursive --no-save <pkg>when the vulnerable package is declared across multiple workspaces. For npm it meansnpm update --workspace=<path>ornpm update --workspaces. Yarn keeps the genericyarn upgrade <pkg>since its workspace protocol doesn't need path targeting. Workspace paths are collected from all dependency paths (not just the shortest), so every affected workspace is captured.pnpm-workspace.yaml support —
readDirectDependencyNamesnow falls back to readingpnpm-workspace.yamlwhenpackage.jsonhas noworkspacesfield. This was blocking correct direct-dependency detection in pnpm monorepos that use the dedicated YAML file (e.g. valibot), which in turn causedsimple-gitand similar packages to receive no workspace-scoped fix command.Section rendering fix —
parent-updatetargets now get their own titled sections ("Critical severity parent updates within range", "High severity parent updates within range") instead of being merged into theurgentdirect-fix sections. This eliminates the two-table rendering issue where a direct-install table and a lockfile-refresh table appeared inside the same section.Fix coverage count — Both the terminal output and the HTML report now show how many findings the plan covers after all commands: "Running all commands above should fix X of Y findings." The count is computed by checking each finding against the final plan using the existing
findSuggestedCommandForFindinglogic.HTML display fix — The HTML report's fix plan target list now uses
displayTargetVersion("within current range") instead of the raw semver forparent-updatetargets, matching the terminal output.Closes #450