matteocervelli/llms

deps

Audit dependency freshness — scan outdated deps and CVEs, classify severity, record update/defer/skip decisions in Atrium, gate PASS/WARN/FAIL.

First seen May 25, 2026

Installation

$ npx skills add matteocervelli/llms --skill deps

Summary

  • Audit dependency freshness — scan outdated deps and CVEs, classify severity, record update/defer/skip decisions in Atrium, gate PASS/WARN/FAIL.
  • Use when checking for outdated packages or deciding whether to upgrade.
  • Trigger on "outdated dependencies", "dependency audit", "are my deps up to date", "should I upgrade".

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from matteocervelli/llms · top by installs.

npx skills add matteocervelli/llms

Browse all from matteocervelli/llms

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Stars 25
License LICENSE
Default branch main
Open issues 0
Status Active

Skill metadata

Parsed from SKILL.md frontmatter.

Allowed toolsRead, Bash, Grep, Glob

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 12,005 B
  • docs SUMMARY.md 331 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 7 installs

SKILL.md

/deps — Dependency Health & Decision Tracker

Scans project dependencies for outdated versions and CVEs, classifies severity, and records human decisions (update / defer / skip) in Atrium so the reasoning survives across sessions.

Data flow: /deps scan both reads AND writes to Atrium:

  • Reads: existing decisions to mark assessed deps
  • Writes: fresh outdated findings via POST /api/dev-projects/sync (keeps Atrium current

between scheduled audit runs)

Graceful degradation: When Atrium is unreachable, scan/classify still works locally. Decision storage and decision-coverage checks are silently skipped with a note.

Quick Start

/deps                        # summary: outdated deps + decision status for current project
/deps scan                   # full scan → PASS/WARN/FAIL gate (used by /health deps)
/deps decide                 # interactive: assess each unassessed finding, record to Atrium
/deps status                 # fetch current snapshot from Atrium (deps + active decisions)
/deps history                # fetch version changelog from Atrium (newest first)

Invoked by: /health deps as part of the full project health audit.


Atrium URL Resolution

All subcommands that talk to Atrium resolve the base URL in this order:


Subcommand: /deps (summary)

Show dependency status for the current project — outdated count by severity, decision coverage.

Steps:

  1. Detect project slug from current directory (last segment of pwd).
  2. If Atrium unreachable: fall through to local scan mode (show outdated only, no decisions).
  3. If Atrium available: show dep table with decision column.

Output:

## Dependency Status — <project> — <date>

  next                 14.2.0 → 15.0.0   [HIGH]     DEFERRED until 2026-04-27
  fastapi              0.109.0 → 0.115.0  [MEDIUM]   unassessed
  httpx                0.27.0 → 0.28.0    [LOW]      unassessed

Summary: 1 CRITICAL · 0 HIGH unassessed · 2 MEDIUM unassessed
Run `/deps decide` to record decisions. Run `/deps scan` for full gate.

Subcommand: /deps scan

Full dependency scan producing a Deps [PASS|WARN|FAIL] gate. Used by /health deps.

Step 1 — Detect ecosystems

Scan the current directory for manifest files:

HAS_PYTHON=false; HAS_NODE=false; HAS_RUST=false; HAS_GO=false
[ -f pyproject.toml ] || [ -f requirements.txt ] || [ -f setup.py ] && HAS_PYTHON=true
[ -f package.json ] && HAS_NODE=true
[ -f Cargo.toml ] && HAS_RUST=true
[ -f go.mod ] && HAS_GO=true

If no manifests found: output Deps [SKIP] — no manifest files found, stop.

Step 2 — Collect outdated packages

Run package manager outdated commands. Parse into a unified list of findings.

Each finding has: package, ecosystem, currentversion, availableversion

Python:

# uv preferred; fallback to pip
if command -v uv &>/dev/null; then
  uv pip list --outdated --format json 2>/dev/null
else
  pip list --outdated --format json 2>/dev/null
fi

Parse: jq '.[] | {package: .name, ecosystem: "python", currentversion: .version, availableversion: .latest_version}'

Node.js:

npm outdated --json 2>/dev/null || true
# npm outdated exits non-zero when outdated deps exist — `|| true` prevents abort

Parse: jq 'toentries[] | {package: .key, ecosystem: "npm", currentversion: .value.current, available_version: .value.latest}'

Rust (if cargo-outdated installed):

if command -v cargo-outdated &>/dev/null; then
  cargo outdated --format json 2>/dev/null
fi

Parse the dependencies array. If cargo-outdated not installed: note "install cargo-outdated for Rust dep checking" and skip.

Go:

if [ "$HAS_GO" = "true" ]; then
  go list -m -u -json all 2>/dev/null | jq -s '.[] | select(.Update != null) |
    {package: .Path, ecosystem: "go", current_version: .Version, available_version: .Update.Version}'
fi

Step 3 — Run security audits

Python:

pip audit --format json 2>/dev/null

Parse: extract packages with vulns list non-empty. Each vuln has id (CVE/GHSA), fix_versions.

Node.js:

npm audit --json 2>/dev/null || true

Parse: jq '.vulnerabilities | to_entries[] | {package: .key, severity: .value.severity, cves: [.value.via[] | select(type=="object") | .cve // .url]}'

Rust (if cargo-audit installed):

if command -v cargo-audit &>/dev/null; then
  cargo audit --json 2>/dev/null
fi

Step 4 — Classify severity

For each finding, assign severity:

Severity Condition
critical Has CVE IDs OR package is EOL (detected by pip-audit fix_versions empty)
high Major version bump: availableversion major > currentversion major (semver X changed)
medium Minor version bump: major same, minor changed
low Patch only: major.minor same, patch changed

Semver parsing (bash):

major() { echo "$1" | cut -d. -f1 | tr -dc '0-9'; }
minor() { echo "$1" | cut -d. -f2 | tr -dc '0-9'; }

Security audit findings always override to critical regardless of version bump type.

Merge: if a package appears in both outdated and audit lists, take the higher severity and union the CVE IDs.

Step 5 — Fetch decisions from Atrium

SLUG=$(basename "$(pwd)")

DECISIONS=$(curl -sf --max-time 5 \

If DECISIONS is empty: mark all findings as unassessed, skip coverage check.

For each finding:

  • If an active decision exists for (package, ecosystem): mark as assessed, show decision + review_at.
  • Check GET /{slug}/dep-decisions/overdue — any overdue decisions escalate to critical.

Step 6 — Push fresh findings to Atrium

Construct a POST /api/dev-projects/sync payload from the scan results. This keeps Atrium current between scheduled audit runs.

# Build deps array as JSON
DEPS_JSON=$(jq -n \
  --argjson findings "$FINDINGS_JSON" \
  '$findings | map({
    package: .package,
    ecosystem: .ecosystem,
    current_version: .current_version,
    available_version: .available_version,
    severity: .severity,
    cve_ids: (.cve_ids // []),
    is_dev_dep: false
  })')

SYNC_PAYLOAD=$(jq -n \
  --arg name "$SLUG" \
  --arg slug "$SLUG" \
  --arg path "$(pwd)" \
  --argjson deps "$DEPS_JSON" \
  '{projects: [{name: $name, slug: $slug, path: $path, deps: $deps}]}')

  -H "Content-Type: application/json" \
  -d "$SYNC_PAYLOAD" >/dev/null 2>&1 || true

Skip silently if Atrium unreachable.

Step 7 — Gate and output

Gate logic:

Gate Condition
PASS 0 critical findings AND 0 unassessed high findings AND 0 overdue decisions
WARN 0 critical BUT unassessed high/medium findings exist OR ≥1 decision due within 7 days
FAIL Any critical (CVE or EOL) OR any overdue deferred decision
SKIP No manifest files found

Output format (matches /health report style):

### Deps [PASS|WARN|FAIL]

Scanned: python (pyproject.toml), npm (package.json)
Date: YYYY-MM-DD

| Package  | Ecosystem | Current  | Available | Severity | Decision          |
|----------|-----------|----------|-----------|----------|-------------------|
| next     | npm       | 14.2.0   | 15.0.0    | HIGH     | DEFERRED 2026-04-27 |
| fastapi  | python    | 0.109.0  | 0.115.0   | MEDIUM   | unassessed        |
| httpx    | python    | 0.27.0   | 0.28.0    | LOW      | unassessed        |

- ✗ 0 CRITICAL
- ⚠ 1 unassessed HIGH
- ⚠ 2 unassessed MEDIUM
- ✓ 1 DEFERRED (within review date)

Summary line for /health report: Deps [WARN] 0 critical · 1 unassessed HIGH · 2 unassessed MEDIUM


Subcommand: /deps decide

Interactive decision workflow. For each unassessed finding (sorted by severity desc), present options and record the decision in Atrium.

Steps:

  1. Run /deps scan to get current findings.
  2. Filter to unassessed only.
  3. For each finding (CRITICAL first, then HIGH, MEDIUM, LOW):
─────────────────────────────────────────────────
Package:   next  (npm)
Current:   14.2.0  →  Available: 15.0.0
Severity:  HIGH (major version bump)
CVEs:      none
─────────────────────────────────────────────────

Decision:
  [u] update   — will update now (no Atrium record needed)
  [d] defer    — not now, but schedule review
  [s] skip     — permanently skip this version jump

Choice:
  1. For update: Record nothing in Atrium (dep will disappear after update+rescan).

Print: → Marked for update. Run update commands after this session.

  1. For defer:

- Prompt: Rationale (why not now)? - Prompt: Review in how many days? [30]

  1. For skip:

- Prompt: Rationale (why skip this version permanently)? - POST with review_at: null

  1. After all findings processed, print summary:
Decisions recorded: 2 deferred · 1 to update · 1 skipped
Run `/deps scan` to verify gate status.

Atrium unavailable: If POST fails, print the decision in a copyable format and suggest recording manually later.


Subcommand: /deps status

Fetch the current dep snapshot + active decisions from Atrium.

SLUG=$(basename "$(pwd)")
echo ""
echo "Active decisions:"
  jq '.[] | "\(.package) [\(.ecosystem)]: \(.decision) — \(.rationale) (review: \(.review_at // "never"))"'

If project not found in Atrium (404): print "Project '${SLUG}' not yet registered in Atrium. Run /deps scan to register and populate."


Subcommand: /deps history

Fetch dep version changelog from Atrium — when did versions change and what CVEs were present.

SLUG=$(basename "$(pwd)")
  jq '.[] | "\(.detected_at[:10]) \(.package) [\(.ecosystem)]: \(.from_version // "new") → \(.to_version)  severity=\(.severity)"'

Decision Recording Format

When recording to Atrium (POST /api/dev-projects/{slug}/dep-decisions):

{
  "package": "next",
  "ecosystem": "npm",
  "current_version": "14.2.0",
  "available_version": "15.0.0",
  "decision": "defer",
  "rationale": "Breaking changes in App Router, assess after migration guide",
  "review_at": "2026-04-27T00:00:00Z",
  "decided_by": "matteo",
  "session_id": null
}

decided_by is optional — use whoami output if available.


Thresholds

Gate Condition
PASS 0 critical · 0 unassessed HIGH · all decisions within review date
WARN 0 critical · unassessed HIGH/MEDIUM exist · OR ≥1 decision due within 7 days
FAIL Any CRITICAL (CVE/EOL) · OR any overdue deferred decision
SKIP No manifest files found