plugins/lt-dev/skills/maintaining-npm-packages/SKILL.md
Analyzes and optimizes npm package dependencies across 5 maintenance modes: FULL (update all), DRY-RUN (analysis only), SECURITY-ONLY (urgent CVE fixes), PRE-RELEASE (conservative patch-only), POST-FEATURE (cleanup after development). Activates when user mentions "update packages", "pnpm audit", "npm audit", "check dependencies", "security fix", "outdated dependencies", "deprecated packages", "devDependencies", "pre-release cleanup", "post-feature housekeeping", "remove unused packages", or package.json optimization. NOT for @lenne.tech/nest-server version updates (use nest-server-updating).
npx skillsauth add lennetech/claude-code maintaining-npm-packagesInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
"vite": ">=7.3.2" to pnpm.overrides lets pnpm silently install 8.x.y on the next install, causing major-version cascading regressions. Override targets MUST be exact ("vite": "7.3.2"). See "Override Safety Rule" below for the real-incident reference from April 2026. The LEFT side of an override may carry a range (to select affected versions); the RIGHT side must be fixed.>= the advisory's fixed-in version. Pinning uuid to 11.1.0 (exact, same major) when the fix landed in 11.1.1 leaves the advisory open — the override silently "works" but resolves a still-vulnerable version. After EVERY override, re-run audit and confirm the targeted package is gone. If it still appears, the target is one patch too low or the selector mis-scoped — bump it; do NOT record it as "blocked" or "needs a framework update".npm audit and pnpm audit disagree on the same dependencies — different package managers resolve transitive versions differently (pnpm floats to the newest in-range patched release; npm can keep an older locked one) and the override block lives in different places: overrides (npm), pnpm.overrides (pnpm), resolutions (yarn). A reference starter reporting "0 vulnerabilities" under pnpm does NOT mean an npm-based consumer is clean. Always audit with the PROJECT's own package manager, and target the patched versions the reference resolves to.pnpm audit --fix --force can cause major version jumps — Step 3 of the escalation ladder is destructive. It will happily upgrade a transitive dependency from ^1.x to 3.x if that closes the CVE. Always verify pnpm run build and the full test suite after using it, and prefer a scoped override for transitives where a compatible patch exists.devDependencies often lag — @types/* packages in particular remain flagged as deprecated for months after the upstream merges types natively. Don't remove them blindly — check the affected imports still resolve via the new inline types before deleting.packageManager field locks pnpm/npm/yarn version — When running maintenance across a monorepo, the packageManager: "[email protected]" field in the root package.json pins the exact version. Upgrading pnpm without also bumping this field causes CI and local runs to diverge silently.pnpm auditdependencies vs devDependenciespackage.jsonFor comprehensive npm package maintenance, use the lt-dev:npm-package-maintainer agent via the maintenance commands.
| User Intent | Correct Skill | |------------|---------------| | "Update npm packages" | THIS SKILL | | "npm audit fix" | THIS SKILL | | "Remove unused dependencies" | THIS SKILL | | "Update nest-server to v14" | nest-server-updating | | "Fix NestJS service" | generating-nest-servers |
generating-nest-servers - For NestJS development when dependencies affect the serverusing-lt-cli - For Git operations after maintenancenest-server-updating - For updating @lenne.tech/nest-server (uses this agent internally)| Command | Mode | Use Case |
|---------|------|----------|
| /lt-dev:maintenance:maintain | FULL | Complete optimization (remove unused, recategorize, update all) |
| /lt-dev:maintenance:maintain-check | DRY-RUN | Analysis only - see what would be done without changes |
| /lt-dev:maintenance:maintain-security | SECURITY | Fast security-only updates (audit vulnerabilities) |
| /lt-dev:maintenance:maintain-pre-release | PRE-RELEASE | Conservative patch-only updates before a release |
| /lt-dev:maintenance:maintain-post-feature | FULL | Clean up after feature development |
/lt-dev:maintenance:maintain (FULL MODE)Recommend when user wants:
/lt-dev:maintenance:maintain-check (DRY-RUN)Recommend when user wants:
/lt-dev:maintenance:maintain-security (SECURITY-ONLY)Recommend when user mentions:
pnpm audit vulnerabilities/lt-dev:maintenance:maintain-pre-release (PRE-RELEASE)Recommend when user mentions:
/lt-dev:maintenance:maintain-post-feature (POST-FEATURE)Recommend when user:
The lt-dev:npm-package-maintainer agent performs 4 priorities:
pnpm.overrides entriesAll operations ensure pnpm run build and pnpm test pass before completion.
When the agent ADDS an entry to pnpm.overrides (typically to force a security-patched version of a transitive dependency), the override target MUST be a fixed version — never a range like ">=X", "^X", or "~X".
| Correct | Incorrect | Why |
|---|---|---|
| "vite": "7.3.2" | "vite": ">=7.3.2" | >= is unbounded — pnpm will install 8.x.y if available |
| "@apollo/server": "5.5.0" | "@apollo/server": "^5.5.0" | Defeats the purpose of an override |
| "vite@>=7.0.0 <7.3.2": "7.3.2" | "vite@>=7.0.0 <7.3.2": ">=7.3.2" | Range on the LEFT selects affected versions; the RIGHT must still be fixed |
Why this matters: In April 2026 the TurboOps monorepo received an override "vite@>=7.0.0 <=7.3.1": ">=7.3.2" from a security maintenance run. Because the target ">=7.3.2" was unbounded, pnpm silently installed [email protected] (major version jump), which broke peer dependencies in @nuxt/test-utils, dropped drizzle-orm from better-auth, and caused 13 e2e test regressions. The fix was switching every override target to a fixed version.
Reference implementation: https://github.com/lenneTech/nest-server-starter/blob/main/package.json — canonical example of correctly-written pnpm.overrides for the lenne.tech stack. Align with this file when in doubt. The detailed rule is in @lenne.tech/nest-server/.claude/rules/package-management.md → "Overrides".
When audit reports vulnerabilities, resolve them in this order. Most are fixable without a major upgrade or a framework bump — escalation is the last resort, not the first diagnosis.
via chain down to the leaf. Fix the root once and every dependent clears (e.g. a single uuid override clears the whole Apollo + compodoc + gaxios chain).npm view <pkg> versions / pnpm view). The target MUST be >= the fixed-in version — confirm this explicitly, it is the #1 silent-failure trap."pkg": "x.y.z") when every instance must move; use a version-selector key ("pkg@<bad-range>": "x.y.z" or "pkg@<exact-bad>": "x.y.z") when other majors must stay (e.g. force [email protected] → 3.1.5 without touching the 9.x/10.x installs glob/ts-morph/nodemon need). npm overrides are GLOBAL by default — one bare key governs every nested instance.package.json (dependencies / peerDependencies) — a "framework-mirror" assumption that the framework does not actually back is a removal candidate, not a keeper./lt-dev:maintenance:maintain-check first (safe, no changes)/lt-dev:maintenance:maintain-security (fast, focused)/lt-dev:maintenance:maintain-pre-release (conservative)/lt-dev:maintenance:maintain (comprehensive)When dependency conflicts or unclear version combinations arise during maintenance, the lenne.tech starter templates provide validated package constellations as reference:
| Project Type | Raw package.json URL |
|--------------|------------------------|
| Frontend (projects/app/, packages/app/) — Nuxt/Vue | https://raw.githubusercontent.com/lenneTech/nuxt-base-starter/main/package.json |
| Backend (projects/api/, packages/api/) — NestJS | https://raw.githubusercontent.com/lenneTech/nest-server-starter/main/package.json |
| Framework core — @lenne.tech/nest-server | https://raw.githubusercontent.com/lenneTech/nest-server/main/package.json |
When to consult the templates:
ERESOLVE errors or peer dependency warnings during install@nestjs/*, nuxt + modules)pnpm.overrides entries for known transitive CVEsHow to apply: Fetch the raw package.json via WebFetch and diff against the current project. Use the starter versions as ground truth for framework core + direct ecosystem. Do NOT blindly downgrade project-specific dependencies to match the starter.
Override documentation pattern: The starter uses a parallel //overrides block in package.json with one comment per override (CVE / transitive chain / removal condition). Mirror this pattern when adding new overrides — undocumented overrides accumulate and become unmaintainable. The full rule is in @lenne.tech/nest-server/.claude/rules/package-management.md → "Overrides".
development
Single source of truth for the lenne.tech fullstack production-readiness checklist. Defines the eight pillars (configuration & secrets, observability & logging, health & lifecycle, security hardening, data durability, resilience under load, deployment hygiene, runbook & rollback) with concrete file/line evidence requirements per pillar, severity classification (Critical / Major / Minor), and a canonical machine-parseable report block. Activates whenever an agent or command needs to gate a release on production-readiness — currently used by /lt-dev:production-ready, lt-dev:production-readiness-orchestrator, and the devops-reviewer (read-only). NOT for OWASP-style code-level security review (use security-reviewer). NOT for npm dependency audits (use maintaining-npm-packages).
development
Single source of truth for executing GitLab CI/CD pipelines locally with the same image, env vars, and service containers as the real runner — so pipeline failures are caught before push. Defines pipeline discovery (.gitlab-ci.yml + includes), per-job execution via gitlab-runner exec, service-container orchestration (Mongo, Redis, MailHog), env injection without secrets, cache/artifact handling, and a job-by-job verdict report. Also describes the GitHub Actions equivalent via act for projects that mirror to GitHub. Activates whenever an agent or command needs to validate that the CI pipeline will pass — currently used by /lt-dev:production-ready and lt-dev:production-readiness-orchestrator. NOT for running the local check script (use running-check-script). NOT for writing or refactoring CI configs (use the devops agent).
development
Single source of truth for designing, running, and interpreting k6 load tests against lenne.tech fullstack APIs. Defines installation paths (brew, docker, npm), the three canonical scenarios (smoke / load / soak), endpoint discovery from the generated SDK, realistic Better-Auth login flows, threshold defaults for ~10 concurrent users (p95 < 500ms, error rate < 1%, http_req_failed < 1%), result interpretation, and the optimisation ladder when the system fails (DB indices, query rewrites, caching, connection pool sizing, rate-limit relaxation, payload trimming). Activates whenever an agent or command needs to validate that the API is stable for ~10 concurrent users performing many actions in short time, or to detect performance regressions via k6. Currently used by /lt-dev:production-ready, lt-dev:production-readiness-orchestrator, and lt-dev:performance-reviewer. NOT for Lighthouse frontend performance (use a11y-reviewer). NOT for unit performance assertions (use the test runner directly).
tools
Migrates lenne.tech projects from the legacy jest+eslint+prettier toolchain to the current vitest+oxlint+oxfmt baseline used by nest-server-starter and nuxt-base-starter. Covers swc decoratorMetadata config, the @Prop union-type fix for SWC, supertest default-import correction, ESM/CJS interop, the Nitro PORT-vs-NITRO_PORT bug, ANSI escape stripping in workspace runners (lerna/nx), free-port logic for check-server-start.sh, the offers-pattern config.env.ts (NSC__-only + fail-fast + auto-derived appUrl), and the multi-phase check-envs.sh smoke test. Activates whenever someone is migrating an existing project to the new toolchain, debugging "Cannot determine a type for the X field" Mongoose errors, ERR_SOCKET_BAD_PORT crashes from check-server-start, or wants to align an existing project with the current starter conventions.