From swe-assistant
Use when the user is about to modify existing code — especially code that is unfamiliar, untested, complex, or scary to touch — and wants to do it safely. Triggers include phrases like "I need to change this old code", "how do I refactor this safely", "this code has no tests how do I touch it", "I'm scared to change this", "about to modify a legacy system", "how should I structure this refactor", "how do I add a feature to this messy code", "should I rewrite this or work with what's there", or asking about safely changing existing code. Walks through Michael Feathers' Legacy Code Change Algorithm (identify change points, find test points, break dependencies, write tests, then make the actual change and refactor), the standard dependency-breaking techniques (extract methods, introduce interfaces, inject control points), the leave-cleaner-than-you-found-it discipline applied opportunistically, the incremental-PR rhythm, and pragmatism about when refactoring is worth the cost. Do not trigger for greenfield code, for tactical syntax or API questions, or for active code reviews (route to code-review).
How this skill is triggered — by the user, by Claude, or both
Slash command
/swe-assistant:changing-legacy-codeThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
*The Missing Readme*, Chapter 3, "Working with Existing Code." The five-step algorithm and dependency-breaking techniques come from **Michael Feathers, *Working Effectively with Legacy Code*** (Prentice Hall, 2004) — the canonical text on this topic. See [`READING-LIST.md`](../../../../READING-LIST.md) for the full reference.
The Missing Readme, Chapter 3, "Working with Existing Code." The five-step algorithm and dependency-breaking techniques come from Michael Feathers, Working Effectively with Legacy Code (Prentice Hall, 2004) — the canonical text on this topic. See READING-LIST.md for the full reference.
Most production code is, in Feathers' famous definition, legacy code: code without tests. The fear of changing it is rational — there's no safety net to catch you when you break something. This skill fires when the user needs to change existing code and wants a structured way to do it without lighting things on fire.
It packages the well-tested algorithm for the task plus the smaller disciplines that make the algorithm actually work in practice (small commits, opportunistic cleanup, pragmatism about whether to refactor at all).
Legacy code is code without tests, not code that's old.
The five steps, in order. The first four are about preparing the ground; the fifth is the actual change.
Where in the code do you actually need to make the change? Be specific. Often this is one or two locations, not "the whole module." Narrow the surface area first.
Where can you add tests that will catch breakage at (or near) the change points?
Most legacy code is hard to test because it has dependencies that are inconvenient (databases, network calls, global state, time, randomness). You need to introduce seams — points where you can substitute the inconvenient real thing for a controlled fake.
Three standard techniques:
Making a private method public (or protected, or package-private just-for-tests) is a tempting shortcut. Resist it. It pollutes the production API forever to solve a test-only problem.
Better options:
Now that there are seams, write tests that capture the current behavior of the code you're about to change.
Now you can make the actual change. With the test net in place, you can:
Run the test suite frequently as you iterate — every few minutes, not at the end of the day. Cheap, fast tests run constantly are the whole point of the scaffold you just built.
The "boy scout rule" (attributed to Robert C. Martin / Clean Code): when you're already changing a piece of code, leave it slightly better than you found it. Rename the confusing variable. Pull the inline logic into a helper. Add the missing docstring.
Be opportunistic, not crusading. Don't go hunting for ugly code to fix — you'll lose the day. Clean what you're already touching, then move on.
Separate cleanup commits from behavior changes. If your work has two parts — "extract validateUser from signup" (no behavior change) and "add email-confirmation step to signup" (behavior change) — make them two commits. This is huge for reviewers and lifesaving for git revert.
For broader frustration with code mess, see software-entropy. For mess that's risen to named technical debt that needs explicit work, see technical-debt.
processPayment" (no behavior change, easy to review). PR 2: "extract chargeCard from processPayment" (no behavior change, easy to verify). PR 3: "use new payment provider in chargeCard" (the actual feature change, now isolated).Refactoring is not always wise, and not always a priority. The cost can exceed the value:
Match the rigor to the risk:
IDE refactoring tools (rename symbol, extract method, inline variable, change signature) are genuinely powerful and far less error-prone than doing those refactors by hand. Use them.
But know their limits:
Follow the Output Protocol: ask one question per turn.
You need two pieces of information to choose the right level of rigor: what's being changed and what tests exist, and how risky the change is. Often the user gives you the first in their initial message; ask only what they haven't already told you.
Start with whichever is missing. Examples:
Ask one, wait for the answer, ask the next in a later turn if you still need it. Never ask both in one message.
For the steps that matter for their situation, ask the question for that step and help them answer it. Don't lecture — get them to do the thinking.
Before they touch code, sketch the commit/PR plan:
For commit message and PR mechanics, route to commit-and-pr-hygiene.
Confirm the plan. Remind them to run tests after every IDE refactor, and to come back if they hit code where they can't find a seam.
code-review.commit-and-pr-hygiene.technical-debt, then come back here for the technique.Surfaced as references but not yet folded in — see READING-LIST.md for full entries.
npx claudepluginhub tmerrien/swe-assistantProvides UI/UX resources: 50+ styles, color palettes, font pairings, guidelines, charts for web/mobile across React, Next.js, Vue, Svelte, Tailwind, React Native, Flutter. Aids planning, building, reviewing interfaces.
Fetches up-to-date documentation from Context7 for libraries and frameworks like React, Next.js, Prisma. Use for setup questions, API references, and code examples.