| name | upgrade-packages |
| description | Delta-driven dependency upgrades โ a script gathers the evidence, you read the artifact and judge. Use when the user asks to upgrade, bump, or CVE-audit dependencies. |
Upgrade packages
A script gathers every release delta, GHSA advisory, and codebase-usage site into one JSON artifact; you read it and judge. Never touch the registry, GitHub, or GHSA directly โ every citation comes from the artifact (diffUrl, changelogUrl, advisory url), so no model priors sneak in. Sources of truth: the artifact, then the codebase. Cite where you read every claim.
This repo uses bun with exact pins in package.json โ bun update alone bumps nothing. Lift an exact pin with bun update <pkg>@<target> (or bun update <pkg> --latest per package) / a package.json edit. Never bun update --latest across the board. The check-updates script is inventory-only.
Phase 1 โ Gather evidence
Run bun run upgrade-packages:evidence (defaults to --out scripts/upgrade-packages/artifact.json; pass --out <path> to override). Requires network access โ the script calls gh api (GitHub releases + GHSA advisories) and bun pm view; a sandboxed network allowlist that blocks api.github.com will make every gh call fail (the artifact degrades to error markers with changelogUrl deep-dive links). Release/advisory data is cached to scripts/upgrade-packages/.cache/ (1h TTL) so re-runs are fast and don't re-trip rate limits. Read the artifact. Schema + how-to-read: REFERENCE.md.
Done when: the artifact exists and you've read inventory, outdated, audit, deltas, and usage.
Phase 2 โ Triage (judge the artifact)
For each outdated package, produce a cited verdict + band:
- band =
bumpClass (patch/minor/major/prerelease). Coupled deps: if a patch bump's peer/dep requires a minor+ bump of another direct dep (check deltas[<pkg>][].peerEngine + the other package's bumpClass), move the coupled set up a band.
- priority-bump if
audit.ghsa verdict is priority-bump โ goes first within its band.
- check-failed if
audit.ghsa verdict is check-failed (gh/parse/cache failure, id:"error") โ inconclusive, not a vuln; re-run evidence or deep-dive the changelogUrl before treating as blocked.
- blocked if any
deltas[<pkg>][].error leaves the range uncovered and the missing version can't be sourced via its diffUrl, OR a breaking/security/peerEngine delta is a break-risk you can't resolve (see Phase 3).
- deferred-major for a major with an unresolved break โ unless it clears a high/critical advisory, in which case surface the tradeoff to the user.
Cite the diffUrl/changelogUrl/advisory url for every verdict.
Done when: every outdated package has a cited verdict, a band, and a coupled-set tag; every priority-bump is flagged for Phase 3.
Phase 3 โ Fact-check break-risk against the codebase
For every break-risk delta (breaking, deprecations, peerEngine, or a behavior-changing fix in security/features โ e.g. callback debounce, CVE patch altering semantics), cross-check usage[<pkg>]. Use callSites (codemap) for blast radius โ where the symbol is actually called, not just imported; importedSymbols + typeOnlySymbols for what's in scope; sites for import locations. Classify: no usage / code-aligned / breaks (needs a code change first). Cite callSites/sites (file:line). A breaks with no code change โ the bump is blocked or deferred.
Done when: every break-risk delta has a citation-backed no usage | aligned | breaks verdict; every breaks has a proposed code change.
Phase 4 โ Apply, gated by risk
Bands: patch โ minor โ major, verify after each per verify-after-each-step. Within each band, priority-bump packages first; coupled sets move up together; prereleases go in the patch band (moving-target, same-major-line gate).
- Patch โ bump together (
bun update <pkg>@<target> per package); run the CI mirror (below).
- Minor โ bump together; same checks.
- Major โ one at a time; land its
breaks code change first, bump, then checks. Defer unresolved majors (cited reason) unless they clear a high/critical advisory.
A bumped parser/resolver/CSS package can change extraction output โ re-run bun run test:golden and regenerate any affected goldens. Re-run bun audit after each band โ a new advisory โ revert that bump and re-research. Commit per band only when the user asked to commit.
Done when: CI mirror (bun run check + bun run build) green for patch + minor; every major green-and-committed/staged or deferred with a cited reason; no breaks unaddressed; final bun audit clean or every remaining advisory documented.
Phase 5 โ Verify (local CI mirror)
Run what .github/workflows/ci.yml runs โ ci.yml is the SSOT:
bun run check โ build + format:check + lint:ci + test + test:scripts + typecheck + test:golden + test:agent-eval (5 of 6 CI jobs: Format, Lint, Typecheck, Test, Build)
bun run build โ covered by check, but re-run explicitly if a bump only touched build tooling (tsdown/oxc) โ do not skip; dep upgrades break the bundler/codegen far more often than types
bun audit โ CI's audit job blocks on high/critical (it greps bun audit output for high: / critical:); treat any high/critical advisory as blocking-with-triage, lower severities as documented
Phase 6 โ Report
Produce: security (advisories โ verdict, with GHSA id + URL + fixed-in), consolidated changeset (rolled up from deltas โ per package current โ target, bucketed breaking/deprecations/features/fixes/peer-engine, one line per delta), adoption opportunities (top ~5 features deltas the codebase isn't using โ usage verdict + file:line + one-line why-adopt + follow-up; non-blocking), bumped packages (band โ version โ why-safe), deferred/blocked (cited reason + file:line), verification results. Every citation from the artifact. If the user asked to commit/PR, hand off to harden-pr full mode.
Done when: report accounts for every non-no-op package and advisory; every citation is real โ no possibly, likely, or unstated assumptions.
Anti-patterns
- โ Touching the registry/GitHub/GHSA directly โ run the script, read the artifact.
- โ
bun update --latest across the board โ per-package --latest/package.json edit for exact pins.
- โ Treating
bun audit as pass/fail โ every advisory needs a cited verdict; a high/critical audit is blocking-with-triage.
- โ Skipping
bun run build โ bundler/codegen breakage beats type breakage for dep upgrades.
Reference