Skip to content
Development
Skill

/update-deps

Update dependencies safely — apply in-range minor/patch updates, then analyze each pending major in parallel and apply only the ones proven safe for this codebase, reporting the rest with justifications.

From plugin
somepulp-agents
78 skills9 agents
Install
$ npx -y skills add jeffrigby/somepulp-agents --skill update-deps --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/update-deps

Context preview

The summary Claude sees to decide when to auto-load this skill.

Update dependencies safely — apply in-range minor/patch updates, then analyze each pending major in parallel and apply only the ones proven safe for this codebase, reporting the rest with justifications.

SKILL.md

update-deps.SKILL.md
name: update-deps
description: Update dependencies safely — apply in-range minor/patch updates, then analyze each pending major in parallel and apply only the ones proven safe for this codebase, reporting the rest with justifications.
when_to_use: When the user asks to "update dependencies", "update deps", "upgrade packages", "bump dependencies", or "check what's safe to update".
argument-hint: "[minors-only|majors-only] [dry-run] [sequential]"
allowed-tools:
  - Bash("${CLAUDE_PLUGIN_ROOT}/scripts/dep-outdated.sh" *)
  - Bash(npm update*)
  - Bash(npm install*)
  - Bash(npm view*)
  - Bash(npm run*)
  - Bash(npx tsc*)
  - Bash(pnpm update*)
  - Bash(pnpm run*)
  - Bash(yarn up*)
  - Bash(yarn upgrade*)
  - Bash(yarn run*)
  - Bash(git status*)
  - Bash(git diff*)
  - Glob
  - Grep
  - Read
  - Agent
  - AskUserQuestion
  - TodoWrite
disable-model-invocation: true

Update Dependencies (Orchestrator)

Bring a JavaScript project's dependencies current in two passes: apply everything the declared ranges already permit, then decide **per package** whether each pending major is safe for *this* codebase — and report the ones that aren't, with a reason the user can act on.

You are the conductor. `major-upgrade-analyzer` subagents do the per-major research; you sequence, gate, apply, and verify.

**Modes requested (optional):** "$ARGUMENTS"

Scope

**JavaScript/TypeScript only** — npm, pnpm, and yarn (classic and berry), detected from the lockfile or the `packageManager` field. If the project has no `package.json`, stop and say so; don't improvise with pip or cargo.

Monorepos are supported: findings are attributed to the workspace that declared them, and upgrades are applied to that workspace rather than the root.

Modes

Split `$ARGUMENTS` on whitespace:

| Token | Effect | | --- | --- | | `minors-only` | Apply in-range updates only. No major analysis. | | `majors-only` | Skip the in-range pass. Analyze and apply majors against the versions already installed. | | `dry-run` | Do all the analysis, change nothing. The approval gate is skipped and the plan is the output. | | `sequential` | Analyze majors one at a time instead of in parallel. Slower; useful for debugging a stuck analyzer. |

Anything else is a scope hint passed to every analyzer (e.g. a path, or "src/ only").

Default: both passes, majors analyzed in parallel, one approval gate covering both.

Workflow

The order matters: **nothing is written until the single approval gate in step 5.** That means the outdated snapshot is taken *before* any update runs, so the plan and the final report can both name exact `from → to` versions.

1. Preconditions

1. Confirm `package.json` exists. If not, stop. 2. Run `git status --porcelain`. **A dirty tree is not a blocker** — this skill never commits and never reverts — but if `package.json` or the lockfile already has uncommitted changes, tell the user before touching them, so they know what's theirs and what's yours. 3. Detect the toolchain:

   "${CLAUDE_PLUGIN_ROOT}"/scripts/dep-outdated.sh --detect

Keep `manager`, `updateCommand`, `updateCommandTemplate`, `majorInstallTemplate`, and `workspaceFlagTemplate` — later steps use them instead of hardcoding a command. 4. **Workspaces**: if `workspaces` is true, note the globs. The report covers **every workspace**, not just the root — the script resolves each finding back to the workspace that declared it. What this means for step 7 is in "Workspace targeting" below; the short version is that a bare install at a workspace root writes to the *root* manifest, which is almost never what you want.

2. Snapshot what's outdated

"${CLAUDE_PLUGIN_ROOT}"/scripts/dep-outdated.sh

Inject the JSON into your context and work from it. Take this snapshot **first** — it is the only record of the pre-update versions, and both the plan and the report depend on it.

Three fields drive everything, and the first two are **independent axes, not a partition**:

  • `upgrade` — the gap from installed to `latest`: `major`, `minor`, `patch`, or `unknown`
  • `inRangeUpdate` — whether the declared range already permits a move (`current` → `wanted`)
  • `type` / `dev` — which dependency section the package lives in

A package can be both (`chalk` 4.1.0, range `^4.1.0`, latest 6.0.0 → in-range to 4.1.2 *and* a major behind). Because they overlap, `counts.inRangeUpdate + counts.major` does not equal `counts.total` — never present it as a breakdown that sums.

Partition the packages:

| Group | Selector | Handled by | | --- | --- | --- | | **In-range** | `inRangeUpdate: true` | Step 6, no analysis — the declared range already permits it | | **Majors** | `upgrade: "major"` | Step 4, one analyzer each; step 5 groups coupled families | | **Unanalyzable** | `upgrade: "unknown"` | Nothing — but they **must** appear in the report's Notes |

Each package also carries `dependents[]` — every workspace that declares it, with that workspace's own range and section. Read it rather than assuming:

  • `type` is the **strictest** section across all consumers, so a package that is a prod dependency in any workspace is reported as one. `dev` is true only when every consumer declares it as a devDependency.
  • `range` is null when workspaces disagree (e.g. `api` pins `^4.0.14` while `client` pins `^4.1.0`). The per-workspace ranges are in `dependents[]`.
  • More than one entry means an upgrade **must touch each of them**. Say so in the plan; a partial upgrade leaves the monorepo inconsistent.

`unknown` means the version couldn't be compared, usually because `current` is null: `node_modules` is missing, or yarn berry is running in PnP mode where there is no `node_modules` tree for npm's resolver to read. If *every* package is `unknown`, say so loudly rather than reporting a clean tree — suggest installing dependencies first, or for yarn PnP, running `yarn install --mode=update-lockfile` and re-running.

Carry `notes[]` through to the final report

Read more
Ships withsomepulp-agents

A plugin marketplace for Claude Code providing specialized agents for code auditing, documentation maintenance, and library/API research.

Get the whole plugin

Other skills on somepulp-agents.