Refactoring
Know what to refactor first, and the plan to do it.
Repowise turns code health into a ranked fix-first queue. Each item names the refactoring, the lines it touches, its effort and the tests to run, ready for you or your agent to apply.
Plans are built without an LLM. Your agent makes the edit.
At a glance
- 7
- named plan types
- From Extract Method to Performance Fix, each with its own detector.
- S to XL
- effort on every plan
- Sized from the target, so the cost sits beside the expected gain.
- Dataflow
- checked Extract Method
- Offered only when every returned value is defined on every path.
- Same commit
- same plans, same ids
- Deterministic, so a plan id you hand an agent stays valid.
Sound familiar?
The debt is known. The order is not.
- 01
The tech debt epic has 300 tickets and no order.
- 02
"Refactor OrderService" has sat in the sprint for a quarter because nobody knows where to cut.
- 03
You asked the agent to tidy one function and it rewrote the file.
- 04
The refactor broke a caller nobody knew about.
What makes it different
What each plan carries.
- Fix first
One queue across every kind of work.
Refactoring plans, performance fixes and the strongest findings, ranked by value, with no kind taking more than three of the first five places.
- Seven plan types
The refactoring, named.
Extract Method, Extract Class, Extract Helper, Move Method, Split File, Break Cycle and Performance Fix.
- Dataflow-checked
Extract Method that keeps behaviour.
A span is offered only when control-flow and dataflow analysis show the extraction is safe.
- Risks first
What else has to change.
The callers and importers of what moves, the files that usually change with it, and any decision that governs the file.
- Tests per plan
The check command, attached.
Measured coverage first, then tests named for the file, then the call graph. No test reaching the code means write one first.
- Payoff
Before and after, recorded.
A resolved plan keeps the target's size before and after and the commit that resolved it, with an applied check for Extract Method.
In depth
From the queue to a plan you can apply.
Fix first
The top of the queue, on httpx.
On httpx, repowise health leads with splitting urlparse in httpx/_urlparse.py: the function has many paths, changed in 5 commits, and its file is imported by 2 others, with an expected gain of 1.0 on that file. It is tiered next, effort M. The header says how many items were eligible and how many were left out and why, so the short list is never a mystery.
- Why it ranks
- Paths, churn and importers, in one sentence.
- Expected gain
- Health the change would recover on that file.
- Tier and effort
- Now, next or later; S to XL.
- What was left out
- Tests, tooling and history-only files, counted.
$ repowise healthFix first (3 of 9 eligible items, 1 due; 37 in the inventory, tests, tooling and history-only files left out) 1. Split urlparse into 6 helpers (+1 more step) next, effort M +1.0 health on this file httpx/_urlparse.py:213 urlparse has many paths; easier to read and change once split; function changed in 5 commits; its file is imported by 2 files, changed 1 time in 90 days, tests run 100% of its lines. 2. Reduce the branching in __init__ later, effort M httpx/_config.py:86 Code health: 7.61/10 [Good], Worst: 2.74/10 (httpx/_client.py)Extract Method
A span, a signature and a blast radius.
This plan on httpx lifts lines 465 to 474 out of normalize_path into a helper that takes components and returns output. It removes 5 from the function's cyclomatic complexity, touches no caller (blast radius local) and is rated high confidence, effort S.
- Span
- The exact lines to move.
- Params and returns
- From reaching definitions and liveness.
- Blast radius
- Local: no caller has to change.
- Impact
- 0.194 health recovered on the file.
Lift lines 465 to 474 out of normalize_path
confidence higheffort S"refactoring_type": "extract_method","target_symbol": "normalize_path","plan": { "span": {"start": 465, "end": 474}, "params": ["components"], "returns": ["output"], "suggested_name": "_compute_output"},"evidence": {"slice_nloc": 9, "ccn_removed": 5},"blast_radius": {"scope": "local"},"impact_delta": 0.194,"source_biomarker": "complex_method"Plan types
Seven refactorings, each with its coordinates.
Every plan type answers a specific health finding: a god class or low cohesion gets Extract Class, a long complex function gets Extract Method, duplicated blocks get Extract Helper, a method that uses another class more than its own gets Move Method. Break Cycle names the smallest set of import edges to invert; the redesign around them is yours, so it ranks below the other plan types.
- Deterministic
- Same commit, same plans, same ids.
- Names never invented
- A helper or file name is null when nothing in the code anchors one.
- Risks listed
- Callers, governing decisions, recent commits on the same lines.
- Payoff tracked
- A resolved plan keeps the size before and after.
What each plan names
- Extract Methodthe span, its parameters and return values
- Extract Classthe cohesive groups a class splits into
- Extract Helperevery copy of a duplicated block and where the helper goes
- Move Methodthe class a method's calls actually land in
- Split Filewhich symbols move where, and the import edits
- Break Cyclethe fewest import edges to invert
- Performance Fixone shared change and every call site it fixes
On a real repository
Every plan on one board, ranked.
The refactoring board plots every structural plan by file size and by how much code imports the file, then lists them in the order to do them, each with its effort and confidence. Open one and its drawer shows the steps, the tests that reach the code and a prompt to hand to your agent.

In plain words
A plan names the lines, the signature and the tests.
A health finding says a function is too complex. A plan says which lines to lift out, what the helper takes and returns, which callers change and which tests prove nothing broke. Plans are computed from the same graph, class model and git history as the health score, so the same commit always gives the same plans and the same ids.
How to read it
How the queue reads
- Now
- Worth doing and safe to start. The first step and the check command are on the card.
- Next
- Worth doing, needs judgment. Read the plan's risks before you start.
- Later
- Can wait, and the card says why.
- Effort S to XL
- Sized from the target, so the cost sits beside the expected gain.
How it works
How a plan is built.
- 01 / Score
Find what costs health
Complexity, nesting, cohesion, clones and history, per function and per file. - 02 / Plan
Run one detector per plan type
Each plan is backed by the signals its detector needs, so every suggestion comes with its evidence. - 03 / Rank
Order by value, then tier
A function changed often outranks an equally complex one nobody touches. - 04 / Hand off
Read it as a recipe
Preconditions, steps in order and checks after. Code generation is a separate, opt-in step.
Where it shows up
Shows up where the work already happens.
CLI
The fix-first queue in the terminal, the full refactoring list, and any plan printed as the prompt an agent applies.
repowise health --refactoring-targets
Coding agents
The agent opens a plan by id and gets the recipe: what must hold before the edit, the steps and the checks after.
get_health(plan_id=...)
Dashboard
The refactoring board plots every plan by file size and importers, with filters for type, confidence and effort.
VS Code
The extension's Refactoring view lists the top ranked plans for the repository, and a lens above a symbol offers its plan.
Questions
What people ask before they try it.
What refactoring plans does repowise produce?
Seven types. Extract Class names the cohesive groups of methods and fields a class splits into. Extract Method names a line span to lift out of a function, with the helper's parameters and return values. Extract Helper names every copy of a duplicated block and where the shared helper belongs. Move Method names the class a method's calls actually land in. Split File names which symbols move to which new file and the import edits in each dependent. Break Cycle names the smallest set of import edges to invert. Performance Fix names one shared change for a performance problem and every call site it fixes.
How does it decide what to refactor first?
Fix first ranks by value: how far a function or file is past the size and complexity bars, with a frequently changed function ahead of an equally complex one nobody touches. Items are then tiered now, next or later, and no single kind takes more than three of the first five places while another kind has work worth doing. Extract Class and Move Method plans are listed in the full inventory and join Fix first once their per-language review passes. Tests, tooling, generated and vendored code, gains under half a point and code a sure dead-code finding covers are left out and counted by reason.
Is the suggested Extract Method safe?
A span is offered only when intra-procedural dataflow analysis (control-flow graph, reaching definitions and liveness) shows the extraction keeps behaviour: every value the helper returns is defined on every path, and no try block is separated from its handlers. Spans it cannot prove are not suggested. A span also has to remove at least two decision points and eight lines and be at most 60 percent of the function, so the helper is worth having.
Does repowise change my code?
No. Plans are structured data. Your agent applies a plan as a recipe, or you ask for generated code and get a diff to review. Code generation is off by default, runs only when you ask for it, uses the model you configure and never runs during indexing. The dashboard can export a plan for an agent; it never edits files or runs tests on its own.
Which languages get refactoring plans?
Plans are built from the same parsed graph and class model as code health. Extract Method covers Python, TypeScript, JavaScript (including Svelte, Vue and Astro), Java, Go, C#, Rust, C++, Scala, PHP, C and Apex. Plans on Java, C#, C and C++ files are served as a preview, listed and counted like any other with the measurement behind each one. Code only moves within a language family, so a Move Method never sends a Kotlin method into a Java class.
How do I hand a plan to Claude Code, Cursor or Codex?
Ask the agent to call get_health(only=["fix_first"]) for the queue, then get_health(plan_id="refac...", include=["recipe"]) for one plan. The recipe lists what must hold before the edit (passing tests, a characterization test to add, a decision to read), the edits in order, the checks after and what the edit must not change. From the terminal, repowise health --plan prints the same recipe as a prompt.
How is a plan different from a code smell warning?
A smell says something is wrong. A plan says what to do about it: which lines, which class, which edge, with the effort, the blast radius, the expected health gain and the tests that reach the code. When a detector lacks a signal it needs, it reports nothing, so a gap in the list means no suggestion, never a guessed one.
Last reviewed: October 2026
Get started
See what your codebase should refactor first.
Index a public repository free and open its refactoring board. Hand the top plan to your agent and check the result against the tests it names.