DeepWorkPlan addon that safely upgrades a repo's dependencies — reasoning about the repo's ACTUAL package manager (npm/pnpm/yarn + ncu, pip/poetry/uv, cargo, go mod, bundler, composer, and more) rather than assuming npm — with a batched, validated, revertible workflow that detects the manager and manifests/lockfiles, classifies upgrades (patch/minor/major), upgrades in safe batches, runs the repo's real validation gate after each batch, reverts a failing batch, and summarizes. Near-default — offered for every repo with declared dependencies, and its delegator installs under the onboarding consent unless declined; upgrades themselves never run automatically, only as explicit, gated work. Never required for baseline conformance; reconciles with the repo's existing tooling. Use when the developer wants to bring dependencies up to date without breaking the build.
Resources
3Install
npx skillscat add dailybothq/deepworkplan-vim/deepworkplan-addon-dependency-upgrade Install via the SkillsCat registry.
DeepWorkPlan — Dependency-Upgrade Addon
Safely bring a repo's dependencies up to date with a batched, validated,
revertible workflow. This is the methodology's third addon —
near-default: offered for every repo with declared dependencies, and its/lib-upgrade delegator installs under the onboarding consent unless
explicitly declined. Installing the delegator changes no dependencies — an
upgrade itself always runs as explicit, gated work (a plan task or a direct
invocation). It is never required for a repo to be AI-first.
The rule that overrides everything: REASON about the package manager, then upgrade
The legacy version of this workflow assumed npm. It does not. The first job
is to detect the repo's actual package manager from the manifest and lockfile
that exist (seeSPEC.md§2 andtemplates/ecosystems.md), then drive that
manager's real upgrade and install commands. Never runncu/pnpmin a Go,
Rust, Python, Ruby, or PHP repo. Never assume a lockfile you have not seen.
Read these first (all relative inside the skill)
- `SPEC.md` — the normative (RFC-2119) contract: detection, semver
classification, batched-upgrade rule, validate-after-each-batch gate,
revert-on-failure rule, reconcile-don't-clobber, validation step. - `templates/ecosystems.md` — the per-ecosystem
reasoning table: how to detect each manager and its real detect / classify /
upgrade / install / lockfile commands. Match the row for the detected stack as
a checklist, then verify against the real repo — detected reality wins. - `templates/upgrade-report.md` — the report shape
to summarize what was upgraded, skipped, reverted, and validated. - `templates/lib-upgrade-command.md` — the
/lib-upgradedelegator this addon installs into the target repo's.agents/commands/only when accepted. ../README.md— the addon mechanism (opt-in, reconcile-don't-clobber, contract).
When this runs
- From
onboardPhase 7b — after the core AI-first scaffolding,onboard
offers this addon for every repo with declared dependencies (any manifest
or lockfile) and installs the/lib-upgradedelegator under the onboarding
consent unless explicitly declined; a decline leaves a baseline-conformant
repo with no command. Installing the delegator runs no upgrade — the flow
below always starts from an explicit request. - Directly —
/deepworkplan-addon-dependency-upgradeon an already-onboarded
repo to upgrade dependencies, or via the installed/lib-upgradedelegator.
Trust boundary (write scope)
allowed-tools includes write-capable Edit, Write, and Bash.
Writes: manifests and lockfiles (package.json + package-lock.json /pnpm-lock.yaml, pyproject.toml + lock, Cargo.toml + Cargo.lock, and
equivalents), a batch/upgrade report under the repo's working-state directory,
and per-batch snapshots in that working-state directory. Commits require the
developer's explicit instruction. Remote registry access is limited
to the package manager's own resolution commands (npm view, pip index,cargo update…) — metadata queries and lockfile regeneration, never script
execution. (Ecosystem post-install scripts run only if the developer opts in,
stated per batch.)
It MUST NOT: run a major-version jump that fails the repo's validation gate
and still record the batch as upgraded, commit a lockfile inconsistent with its manifest (a lockfile-only update
within an existing allowed range is valid), force-push or rewrite history, or discard prior successful batches while reverting a later one. Each batch
is revertible from its own pre-batch snapshot, including before any commit.
The flow
Step 0 — Consent + clean tree
- Confirm the developer wants a dependency upgrade (skip silently if declined —
the repo stays baseline-conformant). - Establish a recoverable baseline. Inspect git status and ownership. Use
an isolated checkout or preserve relevant existing changes in a verified
snapshot; never stash, discard or commit unrelated work implicitly. Run the
real gate once to distinguish pre-existing failure from an upgrade failure.
Step 1 — Detect the package manager (the part you MUST reason about)
Detect the manager(s) from the manifest + lockfile that actually exist, never
by assuming npm. Use templates/ecosystems.md:
- JS/TS →
package.json+ which lockfile:pnpm-lock.yaml(pnpm),yarn.lock(yarn),package-lock.json(npm).ncuis the cross-manager
version checker; the install/update verb is the detected manager's. - Python →
pyproject.toml+poetry.lock(poetry) /uv.lock(uv);requirements*.txt(pip / pip-tools);Pipfile.lock(pipenv). - Rust →
Cargo.toml+Cargo.lock(cargo update). - Go →
go.mod+go.sum(go get -u/go getper module +go mod tidy). - Ruby →
Gemfile+Gemfile.lock(bundle update). - PHP →
composer.json+composer.lock(composer update).
A repo MAY have more than one ecosystem (e.g. a JS frontend + a Python
service). Handle each ecosystem with its own manager, in its own batches.
Step 2 — Classify upgrades (patch / minor / major)
For every outdated dependency, classify by semver against the version in the
manifest/lockfile:
- patch
X.Y.Z → X.Y.(Z+1)— safest (bug fixes). - minor
X.Y.Z → X.(Y+1).0— usually safe (additive, backward-compatible). - major
X.Y.Z → (X+1).0.0— breaking changes possible.
Group patch + minor as the auto-batchable set. Majors require explicit
developer approval before inclusion (present them and wait). Upgrade tightly
coupled packages together (e.g. typescript + its plugins; a framework + its
companion packages) so a peer-dependency constraint is not split across batches.
Step 3 — Upgrade in safe batches
Apply upgrades in small, coherent batches — never all at once (that makes a
failure impossible to isolate). A reasonable order: patch batch → minor batch →
each approved major on its own. For each batch, run the detected manager's
approved package/version update commands, restricted to that batch. Resolve
exact target versions before mutation; never use a broad latest/all-packages
command that can pull in an unapproved major or unrelated package. A lockfile-only
update is valid when existing manifest constraints already admit the target.
Before each batch, snapshot every file it may change (including file absence),
record the manager/environment and previous gate, and verify the snapshot is
recoverable. Suppress dependency lifecycle scripts using the manager's supported
controls unless already explicitly authorized; if safe suppression is unavailable,
stop before running them. Validation that executes dependency build hooks needs
that same authorization. The manager owns lockfile regeneration.
Step 4 — Validate after EACH batch (the gate)
After every batch, run the repo's real validation gate — the commands the
repo actually uses, discovered from AGENTS.md Quick Commands /docs/DEVELOPMENT_COMMANDS.md / the manifest's scripts, or the devcontainer'scodecheck/check/fix/test aliases if that addon is present. Examples:pnpm run biome:check && pnpm run astro:check && pnpm run build;ruff check && mypy && pytest; cargo test; go build ./... && go test ./...;bundle exec rspec; composer test. Never invent a gate — use the repo's
real one.
Step 5 — Revert a failing batch
If the gate fails for a batch, revert just that batch and continue:
restore the exact pre-batch snapshot of the manifest, lockfile and other
owned files, preserving earlier successful batches and pre-existing changes.
Never restore from HEAD unless it is proven identical to that snapshot.
Re-sync the environment without advancing resolution or enabling unapproved
scripts; confirm the previous gate again, then record the batch as
skipped/failed with the reason. Retry only with a new hypothesis or narrower selection; after two attempts
without progress, stop blind retries. If restore or its gate fails, stop with
the snapshot and blocker recorded instead of proceeding to another batch. A failing major is set aside, not forced.
Step 6 — Summarize
Produce the report from templates/upgrade-report.md: upgraded (by tier),
skipped (with reason), reverted (with the failing gate), the manager(s) used, the
files changed (manifest + lockfile), and recommended follow-ups. Do not commit
automatically — surface the diff and let the developer commit (suggestchore(deps): …).
Failure-mode guardrails
- Never required, never blocking. If the developer declines, stop cleanly.
- Reason about the manager. Never run npm/ncu in a non-JS repo; never assume a
lockfile you have not seen. - Never all-at-once. Batch so a failure is isolable and revertible.
- Real gate only. Validate with the repo's actual commands, never a guess.
- Revert, don't push through. A failing batch is reverted and recorded, never
force-installed past a broken gate. - Don't hand-edit lockfiles. The manager owns them; regenerate via install.
- Don't auto-commit. Surface the diff; the developer commits.