Dependency upgrade
Skill mickzijdel/dev-hooks/plugins/dev-hooks/skills/dependency-upgrade
Bring a repo's dependencies up to the latest versions across JavaScript (npm/pnpm/yarn), Ruby (bundler), Python (uv/poetry/pip), and GitHub Actions — reading changelogs/migration guides for major bumps, applying the needed code changes, and landing each step as its own verified commit. Use when the user wants to "update my packages", "upgrade dependencies", "bump deps to latest", "check for outdated packages", or do this across all their repos (fleet mode). Gates every commit on a green test suite; defers any major it can't get green to a written report. Pairs with the github-actions skill (Actions pins) and respects dev-env-setup's 4-day dependency cooldown.From its SKILL.md
npx -y skills add mickzijdel/dev-hooks --skill dependency-upgradeAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
9.6 KB, ~2.3k tokens by cl100k_base, as published. Nobody here has run it
dependency-upgrade
Update a repo to the latest packages safely and incrementally: patch/minor in batched per-ecosystem commits, each major in its own commit after reading the migration guide, and nothing committed unless the tests are green. Covers JavaScript, Ruby, Python, and (by delegating to [[github-actions]]) GitHub Actions. This skill does the upgrade work that [[dev-env-setup]] deliberately leaves alone — dev-env-setup pins the tooling and sets the 4-day cooldown; this skill moves the project's own dependencies forward within that policy.
Per-ecosystem commands (list-outdated, upgrade, regenerate lockfile, where changelogs live) are in references/ecosystems.md — read it before upgrading any ecosystem.
Workflow (one repo)
-
Isolate. Work on a clean tree in a dedicated worktree+branch off the local HEAD (never on a dirty main) — see [[using-git-worktrees]]. Run the read-only preflight to see what's present and what to list:
bash "$CLAUDE_PLUGIN_ROOT/skills/dependency-upgrade/scripts/upgrade_inventory.sh" .It reports
has_js/has_ruby/has_python/has_actions, the chosen package manager per ecosystem, and the exact outdated-listing command for each. (--runalso executes the read-only listing commands whose tool is installed.) It reads only manifests (package.json/Gemfile/pyproject.toml/…), so a Python repo whose single-file CLIs carry PEP 723 inline-script deps has a surface the preflight won't list — see the PEP 723 note in references/ecosystems.md (unpinned inline deps are already auto-latest; pinned ones you bump by hand). -
Green baseline — do this first. Run the repo's test suite and confirm it passes before touching anything. Don't upgrade onto a red baseline — you won't be able to tell your bump from a pre-existing failure. Detect the runner from the stack:
uv run pytest/pytest(Python),bundle exec rspecorbin/rails test(Ruby),npm test/pnpm test(JS). If there is no test suite, fall back to the build + linters and say so in the final report — a missing suite is a gap to surface, not a reason to skip verification. If a suite exists but can't run locally (it needs a Postgres/MySQL service, a browser, or other infra that isn't set up), treat that as a local-setup gap to fix and flag to the user, not something to work around — get the dependency running (e.g. start Postgres + create the role/DB sobin/rails testworks) so you can actually verify the upgrade, and tell the user what was missing. Don't push an unverified bump on a boot check alone. -
Respect the 4-day cooldown. The manifests already encode dev-env-setup's supply-chain window (
exclude-newer/cooldown/min-release-age), so the package manager will hold back releases younger than 4 days — that's intended. Don't disable it to grab a fresher release unless the user asks (e.g. an urgent security fix). See the cooldown table in [[dev-env-setup]]. -
Patch/minor pass — batch per ecosystem. For each ecosystem, list outdated (step 1's command), apply the patch + minor upgrades together, and regenerate the lockfile via the package manager (never hand-edit it — see references/ecosystems.md for the exact commands). Run the tests. Green → one commit per ecosystem (
chore(deps): bump JS patch/minor deps). Red → bisect the offending package out (pin it back), commit the rest, and note the held-back one in the report. -
Major pass — one major at a time. Majors carry breaking changes, so handle them singly:
WebFetchthe changelog / release notes / migration guide (npm package "Changelog", RubyGems/GitHub releases, PyPI "Release notes", the project's UPGRADING/CHANGELOG).- Apply the required code changes for that one bump.
- Run the full suite. Green → its own commit (
chore(deps)!: upgrade <pkg> 2 → 3, with a one-line migration note in the body). - Can't get green → revert that single major, append it to a deferred-upgrades report
(
plans/deferred-upgrades.mdin the repo) with why and the manual steps, and move on. Do not leave the tree red.
-
GitHub Actions. Hand the Actions part to [[github-actions]] (
pinact run -uto bump pins to the latest SHAs, thencheck_action_refs.shto verify). Commit it separately (chore(ci): bump action pins to latest). -
Sync the docs. Update the key-package versions recorded in
README.mdandCLAUDE.mdfrom the resolved manifests/lockfiles (this is what thelatest-deps-reminderhook nudges for). Fold it into the relevant commit or its owndocs:commit. -
Finish — and deploy if asked. Summarize upgraded vs deferred (and why). If everything is green, merge the branch back and clean up the worktree (see [[finishing-a-development-branch]]). Then handle deploy per the repo's model (see Fleet mode step 3 for the full split): a push-to-deploy app only gets pushed if the user wants it deployed (else leave it on a branch/PR); a separate-deploy app (Kamal etc.) is pushed normally, and — if the user asked to deploy it — you then run the deploy (
kamal deploy) and report the outcome. Pause and ask the user first when a major touched a public API / data migration / schema, or the diff is large enough to want a second look. Always confirm the deploy intent before deploying (a single repo upgraded on its own counts too, not just fleet runs).
Fleet mode ("update all my repos")
To sweep every repo, mirror the cadence in the [[dev-env-bump-backfill-fleet]] memory and the [[github-actions]] fleet bump — but one isolated agent per repo so they never share state:
- Enumerate + confirm. Start from the dev-env fleet — [[dev-env-setup]]'s
scripts/fleet_roster.shdiscovers every repo carryingDEV_ENV_VERSIONinmise.tomllive (any fleet memory holds per-repo quirks, not the roster) — and cross-check with the remote list:
Show the user the target set and confirm before touching anything — don't sweep in repos they don't want changed.bash "$CLAUDE_PLUGIN_ROOT/skills/dev-env-setup/scripts/fleet_roster.sh" gh repo list "$(gh api user -q .login)" --source --no-archived --limit 200 --json nameWithOwner -q '.[].nameWithOwner' - Ask up front, before upgrading anything — an upgrade only matters once it's deployed, so
get the user's intent first. Ask two things:
- (a) Which repos to exclude from the upgrade entirely.
- (b) Which deployed apps to deploy after upgrading. Name each deployed app and its deploy model (below), and confirm per app — don't assume. Carry the answers into the dispatch.
- Know each repo's deploy model — it decides what "finish" means:
- Push-to-deploy (Vercel / Netlify / GitHub Pages / Streamlit Cloud — the push to the default branch is the deploy): the push ships it. So only push if the user said to deploy this repo; otherwise leave the upgrade on a branch / PR and don't merge to default.
- Separate deploy (Kamal, a
deploy.ymlworkflow,bin/deploy): pushing is safe — it does not ship. Push as normal, then if the user opted to deploy this app, run its deploy step (for Kamal:kamal deploy) and report the result. - No deploy (library / CLI / plugin): just merge + push.
- Dispatch one agent per repo, each in its own worktree/branch (the Task tool's
isolation: "worktree", or [[dispatching-parallel-agents]]), each running the per-repo workflow above. Pass each agent its exclude / push / deploy disposition from steps 2–3, and a stable, correct agent↔repo mapping — if you later message an agent mid-run (e.g. to change the deploy plan), triple-check the agent id matches the repo, or the instruction lands on the wrong repo. - Report a one-line summary per repo at the end — upgraded / deferred, push state (pushed / PR #), and deploy state (deployed / not).
Guardrails
gh/pinact/a package manager missing or unauthenticated → stop and surface it; never guess a version or a SHA.- A repo with a deliberately bespoke/pinned setup → flag it, don't force upgrades.
- Never disable the cooldown or commit a red tree to "make progress" — defer instead.
- Don't auto-run from a hook; this writes commit-tracked changes. It's invoked by the user (the
latest-deps-reminderhook only nudges that deps may be stale).
How this skill is reached
- The
latest-deps-reminderhook flags that a manifest's versions may be stale → run this skill to actually move them forward. - The user asks to "update packages" / "upgrade dependencies" / "bump deps" / do it across all their repos → this skill's description triggers directly.
What ships with it: 2 files
10.8 KB alongside SKILL.md, 1 of them executable
references/
- ecosystems.md5.6 KB
scripts/
- upgrade_inventory.shruns5.2 KB