Features
The Fowler refactoring catalog Kata drives
Kata ships 30+ refactorings from Martin Fowler's Refactoring catalog, every one invokable from the class node in the diagram and every one also exposed over MCP so an external AI agent can drive it. Below is what's in the box, grouped the way Fowler groups them.
What you'll be able to do
- Locate any Fowler intent Kata implements under the Fowler category you already know it by.
- Trigger a refactoring from a node — the same right-click that opens Rename opens every other intent applicable to that node type.
- Trigger the same refactoring from MCP so an external AI agent can drive Kata without a human at the diagram.
- Understand what Kata does not yet cover, and why.
How to invoke a refactoring
- From the diagram: right-click a class, member, or edge. Kata only shows intents whose preconditions are met on that node — you won't see Pull Up Method on a top-level class with no supertype.
- From a code smell: click a 💩 badge and Kata suggests the Fowler intents that typically resolve that smell — Extract Method for Long Function, Extract Class for God Class, Introduce Parameter Object for Data Clumps, and so on.
- From MCP: an external agent calls the
request_refactortool with the target symbol and intent name. Kata returns a unified diff; the agent decides whether to apply. See the MCP API page for the schema.
Every intent returns a preview diff before it touches disk. Apply writes the changes and updates the diagram incrementally.
Composing Methods
Breaking up long methods and cleaning up their internal shape.
- Extract Method — pull a coherent block into a new named method. Kata infers parameters, return type, and access modifier from the captured locals.
- Inline Method — collapse a trivial method back into its callers.
- Replace Temp with Query — replace a local temporary with a call to a query method.
- Introduce Explaining Variable — name a subexpression so a complex condition or calculation reads as prose.
- Split Temporary Variable — give each responsibility of a reused local its own name.
Moving Features Between Objects
Rehoming methods, fields, and whole classes so responsibilities sit where they belong.
- Move Method — move a method to the class it most communicates with. Kata surfaces this as a suggestion when it detects Feature Envy.
- Move Field — move a field to the class that reads it most.
- Extract Class — split a God Class along a natural seam. Kata highlights the candidate seam from the smell index.
- Inline Class — merge a class that no longer earns its own existence back into its main collaborator.
- Hide Delegate / Remove Middle Man — adjust the exposure of chained calls (Message Chains smell).
Organizing Data
Turning primitive data and awkward exposure into typed, encapsulated structures.
- Encapsulate Field — wrap a public field in getter/setter.
- Replace Data Value with Object — promote a primitive that carries meaning into its own type.
- Replace Magic Number with Symbolic Constant — name numeric literals.
- Replace Type Code with Class / with Subclasses / with State-Strategy — three escalating fixes for the same smell (an untyped tag field driving conditional logic).
- Encapsulate Collection — expose a collection through add/remove/iterate rather than a mutable reference.
Simplifying Conditional Expressions
Reducing branching complexity — the Fowler category where a good refactor most directly reads as a smaller function.
- Decompose Conditional — extract the condition and each branch into named methods.
- Consolidate Conditional Expression — merge parallel checks into one clause with an intent-revealing name.
- Replace Nested Conditional with Guard Clauses — turn pyramid-of-doom into early returns.
- Replace Conditional with Polymorphism — the classical escalation when the same switch appears in three places.
- Introduce Null Object — remove null-checks by giving null a typed representative.
Making Method Calls Simpler
Signature-level surgery.
- Rename Method — the flagship intent; every reference in the solution moves, including cross-language ones where Kata can resolve them.
- Add Parameter / Remove Parameter — with call-site updates or defaults.
- Introduce Parameter Object — the fix for Data Clumps.
- Separate Query from Modifier — split a method that returns a value and mutates state.
- Parameterize Method / Replace Parameter with Explicit Methods — two directions on the same axis.
- Replace Constructor with Factory Method — for when construction hides a choice.
Dealing with Generalization
Moving members up and down a type hierarchy, and pulling shared shape into interfaces and superclasses.
- Pull Up Method / Pull Up Field — move a member from all subclasses into their common supertype.
- Push Down Method / Push Down Field — the inverse, when only some subclasses actually use it.
- Extract Superclass — surface commonality across sibling classes into a new base.
- Extract Interface — carve the intent-revealing subset of a class's public surface into an interface, so callers depend on the shape rather than the class.
- Extract Subclass — split a class whose behavior forks along a type-code axis.
- Collapse Hierarchy — merge a subclass and its parent when the distinction no longer earns its place.
- Replace Inheritance with Delegation / Replace Delegation with Inheritance — the two directions across the classical is-a / has-a boundary.
Big Refactorings
The four multi-step campaigns from the last chapter of the book. These run over many files, respect language boundaries, and preview the whole rewrite at once.
- Tease Apart Inheritance — split a hierarchy that's doing two jobs (typically state and variant) into two orthogonal hierarchies.
- Convert Procedural Design to Objects — take a procedural module and turn its data records into typed objects with behavior.
- Separate Domain from Presentation — pull business logic out of a view class into a domain class.
- Extract Hierarchy — split a class carrying a type-code-driven variance into a hierarchy of subclasses.
What is coming next
Extract Variable, Decompose Conditional, and their neighbours are already implemented — the dialog opens on a member you right-click and you get a named variable or a decomposed condition on Apply. The range-picker UI that will let you highlight an arbitrary subexpression inside the code viewer and drive the same intents from that selection is on the roadmap. Until it lands, those intents work at member granularity; if you need finer scope, an AI diff apply covers the gap.