Order
/migrate
discover → transform each → verify → sweep clean
Run a mechanical migration across a whole codebase — discover every call site, transform each in isolation, verify per-site, and gate on a clean sweep (no old-pattern remnants) with the suite green. For API/dependency/pattern/framework migrations.
Carry a repeated, mechanical change across an entire codebase without missing a site or leaving it half-migrated. Discover every occurrence, transform each independently in isolation, verify per site, and close only when a grep for the old pattern comes back empty and the suite is green. The gate is "zero remnants + still green," and nothing is dropped silently.
Input ($ARGUMENTS): the migration — from → to: an API/signature change, a dependency swap, a language/framework idiom, a config format, a renamed symbol. If empty, ask what's migrating to what.
How to run it
Run it in Claude Code
/migrate <from → to — e.g. "moment.js → date-fns" or "callback API → async/await">
<angle brackets> = required · [square brackets] = optional
Step by step
The stages
Seven stages, in order. Two are hard gates — the run stops there until they pass.
-
Stage 0 — Discover every call site
Gate: the migration is only as good as this census
Exhaustively find all occurrences of the old pattern —
grep/globacross the repo for the symbol, import, signature, or idiom (account for aliases, re-exports, string references, config, and docs). Produce a complete inventory with counts and a per-file list. This census is the definition of "done": every item on it must end migrated or explicitly excluded. Note any ambiguous/hand-judgement sites separately. -
Stage 1 — Plan the transform
Define the exact old→new transformation and the per-site verification (the tests/build that prove a site still works). Identify sites that are not mechanical (semantics differ, not just syntax) and flag them for careful individual handling rather than a blind sweep. Batch the inventory by module/ownership.
-
Stage 2 — Isolate
git -C <repo> fetch origin git -C <repo> worktree add <WORKTREE_DIR> -b <BRANCH> origin/<BASE_BRANCH>All transforms land in the worktree; the base branch stays clean.
-
Stage 3 — Transform each batch
Crew:
senior-engineer(agents:senior-engineer× N, parallel, non-overlapping files)Spawn one
TRANSFORMERper batch in a single message (concurrent), each owning a disjoint file set (useisolation: worktreeif they'd otherwise collide). Each applies the exact transform to its sites, preserves behaviour, matches surrounding style, and reports the sites it changed. Handle the flagged non-mechanical sites individually — never blind-replace where semantics differ. -
Stage 4 — Verify + sweep clean
Gate: HARD GATE
Crew:
sdet(agent:sdet)sdetruns the full suite/build on the worktree — everything green.- Sweep: re-grep for the old pattern across the whole repo. It must come back empty (bar the sites you explicitly excluded in Stage 0, which you list). Any straggler → back to Stage 3.
- Push and run the CI gate (poll
gh pr checks; red → pull log, fix, re-push, re-poll — bounded byMAX_FIX_ROUNDS). Never advance red.
If any sites are intentionally left un-migrated, log them loudly in the report and PR — a silent partial migration reads as "done" when it isn't.
-
Stage 5 — Review & deliver
Crew: (agents, on the pushed PR head)
sdet(always): suite green on the PR head; sweep confirmed clean.senior-engineerorarchitect(fresh): spot-checks a sample of transformed sites for correctness and the non-mechanical sites in full — confirms behaviour is preserved, not just that it compiles.
Any
REJECT/FAIL→ fixer loop, re-push, re-gate (bounded), then escalate. Open (or,auto, merge) the PR: body lists the census counts, sites migrated, sites excluded (with reasons), and the green-CI link. -
Stage 6 — Report
The inventory (found / migrated / excluded), the clean-sweep confirmation, review verdicts, fix rounds, and the PR link. Be explicit about anything deliberately left behind.
Config
BASE_BRANCH= default branch.WORKTREE_DIR=../<repo>--migrate-<slug>.BRANCH=chore/migrate-<slug>.TRANSFORMER=senior-engineer.MAX_FIX_ROUNDS=3.MERGE_MODE=manual(autoopt-in).BATCH= group call sites by module/ownership so parallel transformers don't touch the same files.- Correctness bar / test commands = the repo's own. Read them first. Orchestrator owns all git/gh.
Guardrails
- The census in Stage 0 is the contract — every discovered site ends migrated or explicitly excluded; the clean re-grep is the proof.
- No silent truncation. Excluded/skipped sites are listed loudly, never quietly dropped.
- Mechanical ≠ semantic: sites where meaning (not just syntax) changes get individual human-grade handling.
- Isolated worktrees + non-overlapping ownership so parallel transforms don't corrupt each other.
- Bounded loops; never advance a red PR; the reviewer is a fresh agent.
- If a role doesn't resolve to a
.claude/agents/*.md, fall back togeneral-purposewith the brief inlined and note it.
Where this lives
This page is generated from skills/migrate/SKILL.md. The installer copies it to ~/.claude/skills/migrate/SKILL.md for every project, or .claude/skills/migrate/SKILL.md inside a single repo.