| name | migrate |
| description | Migrate dependencies to new major versions — handles breaking changes, API refactoring, package renames, and behavioral differences. Researches migration guides and tooling, then launches dependency-migrator agents. Use this skill when the user wants to upgrade a dependency across a major version, migrate from one library to another (e.g., Moment.js to date-fns), prepare for EOL by upgrading early, or handle any dependency transition that involves more than just changing a version number. Triggers on phrases like 'migrate', 'upgrade to v2', 'move from X to Y', 'end of life', 'EOL', 'deprecated', 'major version upgrade', 'breaking changes'. |
| argument-hint | <package> [from vX] to <vY> [--repos repo1 repo2] |
| user-invocable | true |
| disable-model-invocation | false |
Migrate
Orchestrates complex dependency migrations across one or many repositories. This is a launcher skill — it handles research, planning, and user approval, then delegates the actual migration to dependency-migrator agents (Opus).
Unlike the CVE patcher which does targeted version bumps, migrations involve breaking changes, code refactoring, API replacements, and sometimes entirely different libraries. The migrate skill ensures thorough research happens before any code is touched.
Step 1: Parse Input
The input is flexible — users describe migrations in many ways:
spring-boot to 3.2 # Upgrade to specific version
aws-sdk-java from v1 to v2 # Full version transition
moment to date-fns # Library replacement
lodash 3.x to 4.x --repos api billing # Scoped to specific repos
python 3.8 to 3.12 # Runtime/language upgrade
angular 14 to 17 # Framework multi-version jump
# No args = scan for EOL/deprecated deps
Extract:
- Package/library name (source and optionally target if it's a library swap)
- Current version (or "detect from repo")
- Target version
- Repos: If
--repos is present, filter to those. Otherwise auto-detect.
Step 2: Detect Repositories
Same pattern as other dependency skills:
- Single repo: Current directory has
.git/ → work in it directly
- Multi-repo folder: Subdirectories with
.git/ → work in all or filtered by --repos
For multi-repo with no filter and more than 10 repos, confirm with the user.
Step 3: Research the Migration
This is the most important step. Do not skip or rush it.
3a: Find the migration guide
Use WebSearch to find:
- Official migration guide — the primary source of truth
- Changelog / breaking changes list for the target version
- Migration tooling — does a codemod, OpenRewrite recipe, Rector rule, or official CLI tool exist?
- Community guides — blog posts and GitHub discussions for real-world gotchas
Research queries to try:
"[package]" migration guide v[old] to v[new]
"[package]" breaking changes v[new]
"[package]" upgrade tool codemod
"[package]" v[new] migration issues site:github.com
Use WebFetch on the most promising results to read the full migration guide. Extract actionable steps.
3b: Check for migration tools
Search for ecosystem-specific tooling:
| Ecosystem | Check for |
|---|
| Java/Kotlin (Maven/Gradle) | OpenRewrite recipes (docs.openrewrite.org/recipes), official migration tools |
| PHP (Composer) | Rector rules (getrector.com) |
| JavaScript/TypeScript (npm) | Official codemods (npx @package/codemod), jscodeshift transforms |
| Python (pip/poetry) | pyupgrade, django-upgrade, framework-specific tools |
| Go | go fix, official migration scripts |
| Rust | cargo fix --edition, clippy migration lints |
| Ruby (Bundler) | RuboCop cops, rails app:update |
| .NET (NuGet) | dotnet try-convert, .NET Upgrade Assistant |
3c: If no package specified — EOL/deprecation audit
When the user invokes without a specific package, scan for dependencies that are EOL, deprecated, or approaching end of support:
- Scan dependency manifests for all declared packages
- Check major framework/runtime versions against known support windows
- Use WebSearch to verify EOL status for anything that looks potentially unsupported
- Present findings and let the user choose what to migrate
Step 4: Present Migration Plan
Present a detailed summary to the user and wait for approval before launching any agents:
## Migration: [package] v[old] → v[new]
### Breaking Changes
1. [Change description — e.g., "javax.* namespace renamed to jakarta.*"]
2. [Change description — e.g., "Spring Security: WebSecurityConfigurerAdapter removed"]
3. [Change description — e.g., "Default serialization changed from X to Y"]
### Migration Tooling
- [Tool name]: [what it automates] — will run first
- Manual steps remaining: [what the tool can't handle]
### Runtime Requirements
- Requires: [e.g., Java 17+, Node 18+] — [met/not met in target repos]
### Affected Repositories
| Repository | Current Version | Affected | Notes |
|---|---|---|---|
| my-api | 2.7.18 | Yes | Heavy usage of removed APIs |
| billing | 2.7.18 | Yes | Minimal usage, mostly auto-migratable |
| auth | 3.1.0 | No | Already on 3.x |
### Risk Assessment
- **Low risk**: [repos where migration is mostly automated]
- **Medium risk**: [repos with moderate manual work]
- **High risk**: [repos with heavy usage of removed/changed APIs]
### Verification
- Build verification: always on (mandatory for migrations)
- Test verification: always on (mandatory for migrations)
The user must approve before proceeding. If they want to exclude certain repos or defer high-risk ones, adjust accordingly.
Step 5: Launch Dependency-Migrator Agents
Git workflow (applies to all modes)
Git workflow is not configurable for migrations. Every dependency-migrator agent MUST follow this exact workflow:
- Checkout the default branch (detect with
git symbolic-ref refs/remotes/origin/HEAD, fall back to main then master)
- Pull latest (
git pull)
- Create a migration branch:
chore/migrate-[package]-v[old]-to-v[new]
- Execute the migration (tooling + manual)
- Verify build and tests (mandatory, cannot be skipped)
- Commit with message:
chore(deps): migrate [package] from v[old] to v[new]
- Do NOT push — the launcher handles delivery
Single-repo mode
Launch one dependency-migrator agent with:
Migrate [package] from v[old] to v[new] in this repository.
Repository: [absolute path]
Migration guide: [URL or summary of key breaking changes]
Migration tool: [tool name and command, or "none — manual migration"]
Migration checklist:
[The compiled checklist from research]
Git workflow:
1. Checkout the default branch and pull latest
2. Create branch: chore/migrate-[package]-v[old]-to-v[new]
3. Execute migration
4. Verify build and tests
5. Commit with message: chore(deps): migrate [package] from v[old] to v[new]
6. Do NOT push — stop after committing
Settings: dep_auto_push=false, dep_branch_strategy=branch
Multi-repo mode
Launch one dependency-migrator agent per repository in parallel (background). Each receives:
- The full migration research (guide, breaking changes, tool info)
- Its specific repository path and current version
- The migration checklist
- The git workflow instructions above (checkout default branch, pull, branch, migrate, verify, commit, NO push)
Wait for all agents to complete.
Step 6: Present Summary and Delivery Options
| Repository | Status | Tool Used | Manual Changes | Tests | Branch |
|------------------|-----------|----------------|----------------|--------|-----------------------------------|
| my-api | Migrated | OpenRewrite | 12 files | 98/98 | chore/migrate-spring-boot-2-to-3 |
| billing-service | Migrated | OpenRewrite | 3 files | 45/45 | chore/migrate-spring-boot-2-to-3 |
| legacy-app | Failed | OpenRewrite | — | 12/30 | (not committed) |
For failed repos, include:
- What went wrong (test failures, compilation errors)
- What was already done vs what remains
- Recommendation (manual fix needed, defer, etc.)
Then, for each repository that has successful migrations, ask the user how they want to deliver the changes:
How would you like to deliver these changes?
1. **Create a PR** — push the branch and open a pull request (requires remote access)
2. **Squash merge locally** — squash-merge the migration branch into the default branch locally (no remote interaction)
3. **Exit** — leave the migration branch as-is and print the changes so you can handle it manually
Handling each option:
Option 1 — Create a PR:
- Push the migration branch:
git push -u origin [branch-name]
- Create a PR using
gh pr create with:
- Title:
chore(deps): migrate [package] from v[old] to v[new]
- Body: migration summary including breaking changes addressed, tool used, and verification results
- Report the PR URL
Option 2 — Squash merge locally:
- Checkout the default branch
- Run
git merge --squash [migration-branch]
- Commit with the same message:
chore(deps): migrate [package] from v[old] to v[new]
- Delete the migration branch:
git branch -d [migration-branch]
- Report: "Changes squash-merged into [default-branch]. Ready to push when you are."
Option 3 — Exit:
- Print a summary of what changed:
- Branch name
- Files modified (from
git diff --stat [default-branch]..[migration-branch])
- The commit(s) on the branch
- Report: "Migration branch [branch-name] is ready. You can push, merge, or cherry-pick manually."
In multi-repo mode, apply the same option to all repos unless the user requests per-repo handling.