Ch 10 — Multi-File & Agentic Refactoring

Cross-file edits, parallel agents, and safe rollback — refactoring at scale with AI
High Level
map
Map
arrow_forward
account_tree
Plan
arrow_forward
call_split
Isolate
arrow_forward
edit
Execute
arrow_forward
verified
Verify
arrow_forward
merge
Merge
-
Click play or press Space to begin...
Step- / 8
map
Why Multi-File Refactoring Is Hard
The challenge that separates toy demos from real engineering
The Single-File Illusion
Most AI coding demos show single-file edits: generate a function, fix a bug, write a component. Real codebases don’t work that way. Renaming a type affects every file that imports it. Changing an API response shape requires updating the endpoint, the client, the types, and the tests. A single logical change can touch 20–50 files.
What Makes It Hard for AI
Context limits — 50 files exceed any context window
Implicit dependencies — re-exports, barrel files, dynamic imports
Ordering matters — change the type before the consumers
Cascading failures — one wrong edit breaks everything downstream
Partial visibility — the agent can’t see all affected files at once
Common Multi-File Refactors
// Tasks that always touch multiple files: Rename Variable, function, type, or file across all consumers Extract Pull logic into a shared utility and update all call sites API change Modify endpoint response shape, update client + types + tests Migration Framework upgrade (React class → hooks across 150+ components) Pattern swap Replace one pattern with another (callbacks → async/await) Move Relocate files to new directory structure, fix all imports
Key insight: Multi-file refactoring is where AI coding agents deliver the most value over completions and chat. A 40-hour manual refactoring job can drop to 16–32 hours with agent assistance. But it requires a different workflow than single-file edits.
account_tree
Dependency Mapping: Know What You’re Touching
The first step is always: find every affected file
Before You Change Anything
The most common multi-file refactoring failure: the agent changes the source but misses consumers. Before making any edit, map the dependency graph. Find every file that imports, references, or depends on the thing you’re changing. This is the blast radius.
How Agents Map Dependencies
Grep/search — find all imports of the symbol
AST analysis — parse code into syntax trees, trace references structurally
Type system — use TypeScript’s language server to find all usages
Dependency graphs — tools that pre-index the entire codebase and track file-to-file relationships
The Implicit Dependency Trap
Agents miss indirect references: barrel files (index.ts re-exports), dynamic imports (import()), string-based references (route names, config keys), and reflection. One study found 12 files missed during a prop rename across 50 components due to indirect import paths through shared index files.
The Human Checkpoint
After the agent maps dependencies, review the list before approving changes. Ask: “Are there files you might have missed? Check barrel files and dynamic imports.” Run the type checker or linter after changes to catch anything the agent’s search missed.
Practical tip: Before a large refactor, ask the agent to list all affected files without making changes. Review the list. Add any files it missed. Only then approve the actual edits. This two-step approach catches most dependency gaps.
call_split
Git Worktree Isolation: One Agent, One Branch
The infrastructure pattern that makes parallel agents safe
The Problem with Shared Directories
If two agents edit the same codebase directory simultaneously, you get file collisions, index corruption, and context contamination. Agent A reads a file, Agent B modifies it, Agent A writes its version — B’s changes vanish. Branches alone don’t help because switching branches destroys the working context.
Git Worktrees
A git worktree creates a separate working directory linked to the same repository. Each worktree has its own files, its own branch, and its own index — but shares the same git history. Multiple agents can work in parallel without interfering with each other.
The Setup
// Create isolated worktrees for agents: git worktree add ../project-auth agent/auth git worktree add ../project-api agent/api git worktree add ../project-ui agent/ui // Each agent works in its own directory: ../project-auth/ → Agent 1 (auth refactor) ../project-api/ → Agent 2 (API changes) ../project-ui/ → Agent 3 (UI updates) // The fundamental rule: One agent = one worktree = one branch // When done, merge back to main: git merge agent/auth git merge agent/api git merge agent/ui
Key benefit: If one agent’s changes are bad, you discard that worktree without affecting the others. Each agent’s work is independently reviewable, testable, and revertible. This is the infrastructure that makes agentic refactoring safe at scale.
edit
Execution Strategies: How to Order the Changes
Dependency order, atomic commits, and the verify-after-each pattern
Dependency-Order Editing
Change files in dependency order: types and interfaces first, then implementations, then consumers, then tests. This ensures each file is valid at the time it’s edited, because its dependencies have already been updated. Editing in random order creates temporary broken states that confuse the agent.
Atomic Commits
After each logical group of changes, commit. “Renamed User.name to User.displayName in types” — commit. “Updated all components to use displayName” — commit. “Updated tests” — commit. Small, atomic commits create rollback points. If step 3 breaks, you revert to step 2 without losing step 1.
The Verify-After-Each Pattern
// After each group of changes: 1. Agent makes edits to a file group 2. Run type checker: tsc --noEmit 3. Run linter: eslint . 4. Run affected tests: npm test -- --changed 5. If all pass → commit & continue 6. If any fail → fix before proceeding // Never let errors accumulate. // Fix each failure before moving on. // Accumulated errors are exponentially // harder to debug than isolated ones.
Why this works: Each commit is a known-good state. The agent can always revert to the last passing commit. This transforms a scary 50-file refactor into a series of small, safe, verifiable steps. The total time is longer, but the risk of catastrophic failure drops to near zero.
groups
Parallel Agents: Divide and Conquer
Multiple agents working on the same codebase simultaneously
When to Parallelize
Parallel agents make sense when the refactoring can be divided into independent chunks: different modules, different layers (frontend vs. backend), or different file groups with no shared dependencies. If changes in one chunk affect files in another, keep them sequential.
Three Parallel Patterns
Task-per-agent: Each agent handles a different part of the refactor. Agent 1 updates the database layer, Agent 2 updates the API, Agent 3 updates the frontend. Clear ownership boundaries prevent conflicts.

Ensemble: Multiple agents solve the same problem independently. You pick the best solution. Useful when you’re unsure of the right approach.

Pipeline: Agents work sequentially, each building on the previous agent’s output. Agent 1 maps dependencies, Agent 2 makes changes, Agent 3 writes tests.
Ownership Boundaries
// Clear file ownership prevents conflicts: Agent 1 (branch: agent/db-layer) src/db/* src/models/* prisma/schema.prisma Agent 2 (branch: agent/api-layer) src/routes/* src/middleware/* src/validators/* Agent 3 (branch: agent/ui-layer) src/components/* src/hooks/* src/pages/* // Shared files (types, utils) are edited // by ONE designated agent only. // Human merges all branches at the end.
Critical rule: Never delegate cross-agent conflict resolution to AI. When branches conflict, a human reviews and merges. The agent doesn’t have the full picture of what the other agents did and will make wrong merge decisions.
transform
Codemods & AST Transforms: The Precision Tool
When you need guaranteed correctness across thousands of files
What Are Codemods?
A codemod is a program that transforms code by parsing it into an Abstract Syntax Tree (AST), making structural changes, and writing it back. Unlike find-and-replace, codemods understand code structure: they can rename a function only when it’s called as a method, not when it appears in a string or comment.
AI + Codemods
The most powerful combination: use AI to generate the codemod, then run the codemod across the entire codebase. The AI handles the creative work (figuring out the transformation), and the codemod handles the mechanical work (applying it to every file reliably). This is faster and safer than having the AI edit each file individually.
When to Use Codemods vs. Agent Edits
USE CODEMODS when: Same transformation across 50+ files Pattern is mechanical and repeatable Correctness must be guaranteed Framework migration (React class → hooks) API deprecation (old method → new method) USE AGENT EDITS when: Each file needs different logic Changes require understanding context Fewer than ~20 files affected Transformation is creative, not mechanical You need the agent to reason about each case
The workflow: Ask the AI to write a codemod. Review the codemod on 2–3 sample files. If it works correctly, run it across the entire codebase. This gives you AI creativity with codemod reliability — the best of both worlds.
warning
What Goes Wrong: Failure Modes
The traps that catch even experienced developers
Missed Files
The agent updates 48 of 50 affected files. The two it missed use indirect imports through a barrel file. The code compiles (TypeScript doesn’t catch the runtime issue), but crashes in production when those two components render. Fix: Always run the full test suite after multi-file changes, not just the files the agent touched.
Inconsistent Patterns
The agent applies the new pattern to most files but falls back to the old pattern in a few, creating a codebase with two competing conventions. This happens when the agent’s context window fills up and it loses track of the target pattern. Fix: Use codemods for mechanical changes; use grep to verify consistency after agent edits.
The Snowball Effect
The agent makes a wrong change in file 5 of 50. Files 6–50 are edited based on the wrong assumption. By the time you notice, 45 files have cascading errors. Fix: Verify after each group (the verify-after-each pattern from Step 4). Catch errors at file 5, not file 50.
Merge Conflicts from Parallel Agents
Two agents both edit a shared utility file. Their changes conflict. The merge produces code that neither agent intended. Fix: Assign shared files to one agent only. If both agents need to change a shared file, make it sequential: Agent 1 finishes, commits, then Agent 2 starts from that commit.
The meta-lesson: Multi-file refactoring failures almost always come from insufficient verification, not from the AI making bad edits. The edits are usually fine. The problem is not checking them thoroughly enough before moving on.
checklist
The Multi-File Refactoring Playbook
A step-by-step process for safe, large-scale changes
The Playbook
1. MAP Ask agent to list all affected files. Review the list. Add missed files. Check barrel files and dynamic imports. 2. PLAN Define the change in dependency order. Identify shared files (single-owner). Decide: codemods or agent edits? 3. ISOLATE Create a branch (or worktree for parallel). Ensure clean starting state (all tests pass). 4. EXECUTE Edit in dependency order. Atomic commits after each file group. Verify (typecheck + lint + test) after each.
Continued
5. VERIFY Run full test suite. Grep for old pattern (should be zero). Grep for new pattern (should match count). Manual spot-check 3–5 files. 6. REVIEW Review the diff as a whole. Check for inconsistencies. Look for missed edge cases. 7. MERGE Squash or merge to main. Run CI pipeline. Monitor for runtime errors. // Time investment: 30 min planning saves // 3+ hours of debugging cascading failures.
Key insight: Multi-file refactoring with AI is not “ask the agent and walk away.” It’s a structured collaboration: you map and plan, the agent executes, you verify and review. The 90% time savings come from the agent doing the mechanical editing — but you still own the strategy and quality.