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.

  1. 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.

  2. Seven plan types

    The refactoring, named.

    Extract Method, Extract Class, Extract Helper, Move Method, Split File, Break Cycle and Performance Fix.

  3. Dataflow-checked

    Extract Method that keeps behaviour.

    A span is offered only when control-flow and dataflow analysis show the extraction is safe.

  4. 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.

  5. 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.

  6. 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 health
$ 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)
Real output, repowise 0.59 on httpx, wrapped to fit

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.
plan, extract method, httpx/_urlparse.py

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"
Real plan, repowise 0.59 on httpx, fields trimmed; rename the suggested helper when you apply it

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.
seven plan types

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
The seven plan types and what each names

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.

Repowise refactoring board for repowise-dev/repowise: a scatter of Split File, Break Cycle, Extract Class and Move Method plans by file size and importers, above a ranked list of plans with effort and confidence.
repowise-dev/repowise, the refactoring board

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.

Plans are built during the health pass of every index and update, with no network calls and no re-parse.
  1. 01 / Score

    Find what costs health

    Complexity, nesting, cohesion, clones and history, per function and per file.
  2. 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.
  3. 03 / Rank

    Order by value, then tier

    A function changed often outranks an equally complex one nobody touches.
  4. 04 / Hand off

    Read it as a recipe

    Preconditions, steps in order and checks after. Code generation is a separate, opt-in step.

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.