audit-deps
Run a dependency vulnerability audit and map each advisory to the pracht routes, loaders, middleware, and API handlers that import it — so you know what to retest after upgrading. Use for "audit deps", "scan for CVEs", "npm audit", "which routes use this vulnerable package".
Install
npx skills add https://github.com/JoviDeCroock/pracht/tree/main/skills/audit-deps
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install jovidecroock-pracht@llmmart
git clone https://github.com/JoviDeCroock/pracht.git
The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole jovidecroock/pracht collection as a plugin from our marketplace. Git is the plain clone.
Skill manifest
Pracht Audit Deps
npm audit (or pnpm audit) gives you a list of vulnerable packages. This
skill goes one step further: for each advisory, it tells you which routes
and APIs touch the vulnerable code path so you can prioritize and write
targeted regression tests after upgrading.
Prerequisites: pracht inspect requires a vite config that registers the
pracht plugin.
Step 1: Run the audit
Detect the package manager from the lockfile in repo root; for yarn,
disambiguate Classic vs Berry via the packageManager field in
package.json (fall back to yarn --version):
| Lockfile | Manager | Command |
|---|---|---|
pnpm-lock.yaml |
pnpm | pnpm audit --json |
package-lock.json |
npm | npm audit --json |
yarn.lock |
yarn Classic (yarn@1.x) |
yarn audit --json |
yarn.lock |
yarn Berry (yarn@2+) |
yarn npm audit --json --recursive |
bun.lockb / bun.lock |
bun | bun audit --json (if available; otherwise note as gap) |
Capture the JSON. Track each advisory: package, severity, range, fixed-in.
Step 2: Resolve "which package depends on the vulnerable one"
For transitive vulns, the direct importer matters more than the leaf. Use the package manager:
pnpm why <package>
# or
npm ls <package>
Capture the dependency chain. The first non-pracht-internal direct dependency is the one the user owns.
Step 3: Map to routes/APIs
MCP: when the pracht MCP server is registered (pracht dev-mcp), prefer its
inspect_routes/inspect_api/inspect_build/doctor/verify tools over
shelling out.
For each direct dependency identified in step 2:
- Grep
src/forimport .* from "<dep>"andrequire("<dep>"). - Classify each hit file against the resolved graph — do NOT classify by
directory convention (pages mode uses a configurable
pagesDir, and app layout is not fixed). Frompracht inspect routes --json, match the hit against each route'sfile,loaderFile, andshellFile; resolvemiddlewarenames to files via thedefineApp({ middleware })map in the manifest. Frompracht inspect api --json, match against each API route'sfile. - A hit that matches none of those is a shared module — trace its importers upward until you reach a route, loader, shell, middleware, or API file from the graph.
This produces a "blast radius" per advisory.
Step 4: Categorize urgency
For each advisory, score:
| Factor | Weight |
|---|---|
Advisory severity (critical/high/moderate/low) |
base |
| Reachable from a request handler | +1 tier |
| Reachable from an unauthenticated route | +1 tier |
| Reachable only from build scripts / dev tools | -1 tier |
Build scripts that never ship to runtime (e.g., a Vite plugin used only at build time) are lower priority than a package imported into a production loader.
Step 5: Report
Report severity is the primary scale — error (critical/high reachable from
runtime), warn (moderate, or high but build-time only), info (low, or
unreachable) — with the advisory's own severity as a secondary column:
## error
- <pkg> @ <version> — advisory: <severity> — <CVE>
Direct importer: <dep>
Reachable from:
- GET /api/users (src/api/users.ts)
- SSR /dashboard (src/routes/dashboard.tsx → src/server/db.ts)
Fix: upgrade to <range>
Test after upgrade: <list of routes/APIs above>
End with a one-line verdict: N critical, N high, N moderate, N low — N reachable from runtime.
Step 6: Recommend the upgrade
This skill is report-only — do not run any install or upgrade command. For each fix:
- If the direct dependency has a non-breaking range covering the fix:
recommend running
pnpm up <dep>(or the equivalent for the detected package manager). - If a major bump is required: link to the package's CHANGELOG and recommend a deliberate migration.
- Recommend running
pnpm testand the route-targeted tests derived from step 3 after any upgrade.
Rules
- Always determine the direct importer; transitive-only output is unhelpful.
- Distinguish runtime vs. build-time exposure — they have very different urgency.
- Do not run any upgrade; propose commands only. The user applies them.
- If the audit tool reports zero advisories, still note the package counts and lockfile age — staleness is a precursor to advisories.
- Cross-reference with
pre-deploybefore shipping any post-upgrade build.
$ARGUMENTS
Files (pracht)
-
SKILL.md 5 KB
--- name: audit-deps version: 1.1.1 description: | Run a dependency vulnerability audit and map each advisory to the pracht routes, loaders, middleware, and API handlers that import it — so you know what to retest after upgrading. Use for "audit deps", "scan for CVEs", "npm audit", "which routes use this vulnerable package". allowed-tools: - Bash - Read - Grep - Glob --- # Pracht Audit Deps `npm audit` (or `pnpm audit`) gives you a list of vulnerable packages. This skill goes one step further: for each advisory, it tells you **which routes and APIs touch the vulnerable code path** so you can prioritize and write targeted regression tests after upgrading. Prerequisites: `pracht inspect` requires a vite config that registers the pracht plugin. ## Step 1: Run the audit Detect the package manager from the lockfile in repo root; for yarn, disambiguate Classic vs Berry via the `packageManager` field in `package.json` (fall back to `yarn --version`): | Lockfile | Manager | Command | | -------------------- | -------------- | -------------------------------- | | `pnpm-lock.yaml` | pnpm | `pnpm audit --json` | | `package-lock.json` | npm | `npm audit --json` | | `yarn.lock` | yarn Classic (`yarn@1.x`) | `yarn audit --json` | | `yarn.lock` | yarn Berry (`yarn@2+`) | `yarn npm audit --json --recursive` | | `bun.lockb` / `bun.lock` | bun | `bun audit --json` (if available; otherwise note as gap) | Capture the JSON. Track each advisory: package, severity, range, fixed-in. ## Step 2: Resolve "which package depends on the vulnerable one" For transitive vulns, the direct importer matters more than the leaf. Use the package manager: ```bash pnpm why <package> # or npm ls <package> ``` Capture the dependency chain. The first non-pracht-internal direct dependency is the one the user owns. ## Step 3: Map to routes/APIs MCP: when the pracht MCP server is registered (`pracht dev-mcp`), prefer its `inspect_routes`/`inspect_api`/`inspect_build`/`doctor`/`verify` tools over shelling out. For each direct dependency identified in step 2: 1. Grep `src/` for `import .* from "<dep>"` and `require("<dep>")`. 2. Classify each hit file against the resolved graph — do NOT classify by directory convention (pages mode uses a configurable `pagesDir`, and app layout is not fixed). From `pracht inspect routes --json`, match the hit against each route's `file`, `loaderFile`, and `shellFile`; resolve `middleware` names to files via the `defineApp({ middleware })` map in the manifest. From `pracht inspect api --json`, match against each API route's `file`. 3. A hit that matches none of those is a shared module — trace its importers upward until you reach a route, loader, shell, middleware, or API file from the graph. This produces a "blast radius" per advisory. ## Step 4: Categorize urgency For each advisory, score: | Factor | Weight | | --------------------------------------- | ------ | | Advisory severity (`critical`/`high`/`moderate`/`low`) | base | | Reachable from a request handler | +1 tier | | Reachable from an unauthenticated route | +1 tier | | Reachable only from build scripts / dev tools | -1 tier | Build scripts that never ship to runtime (e.g., a Vite plugin used only at build time) are lower priority than a package imported into a production loader. ## Step 5: Report Report severity is the primary scale — `error` (critical/high reachable from runtime), `warn` (moderate, or high but build-time only), `info` (low, or unreachable) — with the advisory's own severity as a secondary column: ``` ## error - <pkg> @ <version> — advisory: <severity> — <CVE> Direct importer: <dep> Reachable from: - GET /api/users (src/api/users.ts) - SSR /dashboard (src/routes/dashboard.tsx → src/server/db.ts) Fix: upgrade to <range> Test after upgrade: <list of routes/APIs above> ``` End with a one-line verdict: `N critical, N high, N moderate, N low — N reachable from runtime`. ## Step 6: Recommend the upgrade This skill is report-only — do not run any install or upgrade command. For each fix: - If the direct dependency has a non-breaking range covering the fix: recommend running `pnpm up <dep>` (or the equivalent for the detected package manager). - If a major bump is required: link to the package's CHANGELOG and recommend a deliberate migration. - Recommend running `pnpm test` and the route-targeted tests derived from step 3 after any upgrade. ## Rules 1. Always determine the direct importer; transitive-only output is unhelpful. 2. Distinguish runtime vs. build-time exposure — they have very different urgency. 3. Do not run any upgrade; propose commands only. The user applies them. 4. If the audit tool reports zero advisories, still note the package counts and lockfile age — staleness is a precursor to advisories. 5. Cross-reference with `pre-deploy` before shipping any post-upgrade build. $ARGUMENTS
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.