Introducing ruby-upgrade-toolkit

Make Ruby and Rails upgrades a Tuesday-afternoon job, not a multi-week saga.

If you’ve ever upgraded a Rails 5 app to Rails 7, jumped Ruby 2.7 to 3.3 across keyword-argument breaking changes, or untangled a Gemfile that hadn’t moved in three years — you know exactly what I mean.

There’s no shortage of guidance: official Rails upgrade guides, gem-by-gem changelogs, scattered blog posts about Zeitwerk migrations, framework-defaults toggles, and bin/rails app:update diffs. The problem isn’t a lack of knowledge.

It’s that executing the work — sequencing it correctly, handling intermediate version hops, keeping the test suite honest at every step, and not blowing up a Friday production deploy — is mechanical, repetitive, and unforgiving. It’s exactly the kind of work that ought to be automated.

That’s what ruby-upgrade-toolkit does. It’s a Claude Code plugin that gives Claude a structured, repeatable methodology for Ruby and Rails upgrades — separately or together, any version pair. You install it, point it at your project, and it audits, plans, fixes, verifies, and commits — phase by phase, with you in the loop at every checkpoint.

Three modes — pick the one that matches your appetite for risk #

The toolkit ships six commands. You don’t have to memorize them; the modes compose:

The three modes share the same per-phase work — /upgrade is just a loop over /fix next calls with prerequisite checks bolted on. So if you start automated, hit a snag, and want to drop into manual, your in-progress task list comes with you.

Why phased commits matter #

The unit of work in this toolkit isn’t “the upgrade.” It’s the phase. Going Rails 6.1 → 8.0 isn’t one operation; it’s three (6.1 → 7.0 → 7.1 → 8.0). Each phase ends with verification — RSpec green, RuboCop clean, deprecation count, Zeitwerk happy — and a git commit with a detailed message itemizing what changed. Failures pause the pipeline before any commit happens; the working tree holds the problematic state and you decide whether to investigate, retry, or abort. There’s no opaque “rollback” to debug — you just have ordinary git commits at every successful checkpoint, and a dirty tree when something breaks. Bisecting after a regression is a git bisect away.

Estimates aren’t guesses, either. The plan command derives effort, risk, and blast radius from concrete grep counts and bundle outdated output — keyword-argument call sites, deprecated API matches, native-extension gem flags — and ships every total with the formula so you can audit or override it.

Custom rules for project-specific policies #

Released in v0.9: a /rules command for the constraints the toolkit can’t infer on its own. Things like:

Rules live in .ruby-upgrade-toolkit/rules.yml at the project root — committed to your repo, reviewable in PRs like any other config. Every command (audit, plan, fix, upgrade, status) picks the file up automatically. Rule-driven steps appear inline in plan checklists tagged [rule: <id>]; rule outcomes show up in fix’s commit messages so the whole upgrade is auditable in git history. With no rules.yml, every command behaves byte-identically to before — the feature is strictly additive.

Try it #

/plugin marketplace add dhruvasagar/ruby-upgrade-toolkit
/plugin install ruby-upgrade-toolkit@dhruvasagar

Then in any Ruby project:

/ruby-upgrade-toolkit:audit ruby:3.3.1 rails:7.2

And here’s an exerpt of what it produces:

# Ruby Upgrade Audit Report
Current: Ruby 2.7.8
Target:  Ruby 3.3.1
Upgrade Path: 2.7 → 3.0 → 3.1 → 3.2 → 3.3 (4 phases required)

## Test Suite Baseline
- Status: PASSING
- 312 examples, 0 failures

## Critical Issues
### Keyword Argument Mismatches (Ruby 3.0)
- 18 methods with **kwargs or opts={} patterns
- 34 call sites with potential hash/keyword mismatch
- Preview warnings from Ruby 2.7: 22 unique warning sites

### Unsafe YAML.load calls
- 3 occurrences: lib/config_loader.rb, lib/serializer.rb, config/initializers/legacy.rb

## Effort Estimate
Overall: Medium
- Keyword arg fixes: ~34 sites (automated with review)
- YAML fixes: 3 files (automated)
- RuboCop TargetRubyVersion gap: 2.7 → 3.3 (expect new cops)

The audit is read-only — it won’t touch a single file. Read the report, decide whether to keep going, and either run /plan to see the roadmap or /upgrade to execute it.

The full README, all six command references, and four worked walkthrough scenarios (Ruby-only, coordinated Ruby+Rails, Rails-only, and a custom-rules walkthrough using Rails LTS + Brakeman + a gem swap) are at github.com/dhruvasagar/ruby-upgrade-toolkit.

If you’ve been putting off an upgrade, this is the week to start.