look-before-you-leap/skills/refactoring/SKILL.md
Use when refactoring, restructuring, extracting, reorganizing, renaming across files, or moving files. Make sure to use this skill whenever the user asks to: rename a function, class, or type across multiple files; move files or modules to new locations; extract code into new modules, hooks, or utilities; split large files into smaller ones; restructure directory layouts; consolidate duplicate logic into shared abstractions; change naming conventions across the codebase; or clean up messy code by extracting common parts. Uses dep maps (deps-query.py) for instant consumer discovery before changes and regenerates stale maps after. Two modes: Full Mode (contract-based 4-phase refactoring) and Quick Mode (post-step simplification). Do NOT use for: single-variable renames within one function, formatting-only changes, changes within a single file, adding new features, bug fixes, or writing tests.
npx skillsauth add miospotdevteam/claude-control refactoringInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Claude's #1 refactoring failure mode: incomplete refactoring. You rename a function but miss 3 consumers. You move a file but leave stale imports. You extract a module but forget to delete the dead code. The fix: a contract that catalogs everything before you start, so you can verify everything after you finish.
This skill has two modes:
Simplify: true. Progressive, least-invasive-first
cleanup..temp/plan-mode/active/. If none exists,
create one before proceeding (enforcement hooks will block edits without
one).Use when the user asks you to refactor, restructure, extract, reorganize, rename across files, or move files. The 4 phases ensure nothing gets left behind.
Before touching any code, catalog everything that will be affected.
Create refactoring-contract.md in the active plan directory:
# Refactoring Contract: <brief description>
## Targets (what's being refactored)
- [ ] `path/to/file.ts` — function `oldName` (line 42)
- [ ] `path/to/other.ts` — class `Widget` (lines 10-85)
## Exports affected
- [ ] `oldName` from `path/to/file.ts` — used by 4 consumers
- [ ] `Widget` from `path/to/other.ts` — used by 2 consumers
## Consumers (every file that imports/uses a target)
- [ ] `src/routes/dashboard.tsx:7` — imports `oldName`
- [ ] `src/lib/analytics.ts:23` — imports `oldName`
- [ ] `src/components/Panel.tsx:5` — imports `Widget`
- [ ] `tests/file.test.ts:3` — imports `oldName`
## Tests covering targets
- [ ] `tests/file.test.ts` — tests `oldName` directly
- [ ] `tests/dashboard.test.ts` — tests route that uses `oldName`
## Expected after-state
- `oldName` → `newName` everywhere (0 remaining references to `oldName`)
- `Widget` moved to `src/components/Widget.ts` (0 imports from old path)
Dep map integration (TypeScript projects):
Before building the contract, check if dep maps are configured (look for
dep_maps in .claude/look-before-you-leap.local.md YAML frontmatter).
If configured, run deps-query.py on EVERY target file FIRST — this gives
you instant, complete consumer lists across all modules. Dep maps catch
cross-module consumers that grep often misses. If dep maps are NOT
configured, suggest /generate-deps to the user before proceeding.
After the refactoring is complete, regenerate stale dep maps (see Phase 4). File moves, renames, and extractions invalidate existing maps.
How to build it:
deps-query.py for instant DEPENDENTS (do NOT grep for consumers when
dep maps exist); otherwise grep for import statements, direct references,
re-exports. If deps-query.py fails or returns no results, fall back to
grep-based consumer search and note the tool failure in the contract. Be
thorough: search for the function name, the file path in imports, type
references, and string referencesoldName")The contract is your checklist. Every item gets checked off during execution and verified during Phase 4.
Categorize the refactoring to set expectations and scope boundaries.
Categories:
| Type | What changes | Typical blast radius | |---|---|---| | Rename | Names only (variables, functions, types, files) | Every consumer of the renamed symbol | | Extract | Code moves into a new module/function/class | Original file + new file + consumers of extracted code | | Move | Files/code relocates to a different path/module | Every import of the moved file | | Restructure | Internal organization changes (split/merge files, reorder modules) | All files in the affected directory + their consumers |
Set the scope boundary:
deps-query.py (MUST use when dep maps are configured) to trace the chain
instantly — do NOT grep for consumers when dep maps existRule: if the blast radius exceeds 10 files, create a sub-plan with groups. Do not attempt a 15-file refactoring as one step.
User confirmation gate: If the contract's blast radius exceeds 5 files, present the contract summary to the user and wait for confirmation before proceeding. For 5 files or fewer, proceed autonomously.
Apply changes methodically. For each target in the contract:
Execution order (minimizes broken intermediate states):
After every 2-3 file edits, update both the refactoring contract AND the masterPlan progress.
After all changes are applied:
python3 ${CLAUDE_PLUGIN_ROOT}/scripts/deps-generate.py <project_root> --stale-only
This ensures consumers of the refactored code are correctly mapped for
future queries. If many modules were affected, run with --all instead.refactoring-contract.md with results:
## Verification
- Stale references: 0 (grepped for `oldName`, `old/path`)
- Dead code removed: `unusedHelper` from `utils.ts`
- Tests: 47 passed (same as baseline)
- Type checker: clean
- Linter: clean
Use when the conductor dispatches you as a sub-agent after a plan step with
Simplify: true. You are a refinement pass — make code clearer, more
consistent, and simpler without changing behavior.
Announce at start: "Running refactoring quick mode on Step N."
Before touching any code, learn what "good" looks like in this project.
.claude/look-before-you-leap.local.md — check for a
simplifier section in the YAML frontmatter with project-specific
preferences:
simplifier:
prefer_explicit_returns: true
max_function_length: 50
prefer_named_exports: true
If CLAUDE.md and sibling files disagree, follow CLAUDE.md. If CLAUDE.md is silent, follow sibling file patterns. If both are silent, use your judgment.
Before making any simplification edits:
package.json scripts,
Makefile, pyproject.toml, CLAUDE.md, or README.mdThis baseline proves any subsequent test failure was caused by your changes.
Expand your scope iteratively from the modified files outward.
Ring 0: Modified files — Read all files listed in the step's "Files involved" field. These are your primary targets.
Ring 1: Direct imports and consumers — For each modified file: read its
imports (what does it depend on?), find consumers (use deps-query.py if
dep maps are configured, otherwise grep — who imports this file?), read
each direct neighbor.
Ring N: Propagation — If a simplification in Ring 0 or 1 propagates (e.g., renaming an export requires updating consumers), follow that file's imports and consumers.
Hard scope limits:
Stop condition: Stop expanding when no new simplification opportunities are discovered at the current ring. Track which files you've read to avoid cycles.
Apply simplifications in order from least to most invasive. After each level, consider whether the next level is warranted.
Level 1: Cosmetic
Level 2: Structural
Level 3: Internal APIs (requires user confirmation before applying)
When to stop: If you reach Level 2 and the code is already clean, stop. If a simplification is ambiguous (reasonable people could disagree), skip it. If a simplification would make a diff hard to review, skip it.
After all simplifications:
Summarize what you did. The conductor records this in the step's Result field.
Simplification pass on Step N:
- [Level 1] <what you changed> (files: ...)
- [Level 2] <what you changed> (files: ...)
- Reverted: <anything that broke tests>
- Skipped: <anything you considered but chose not to change, and why>
Tests: all passing (N tests, same as baseline)
If you're unsure whether a change is safe, skip it. The goal is confident refactoring with a verified contract, not maximum diff size. A small, safe refactoring is better than an ambitious one that leaves orphaned references.
refactoring-contract.md exists with all targets, consumers, and testsdevelopment
Use after discovery to write implementation plans with TDD-granularity steps. Produces plan.json (immutable definition, frozen after approval), progress.json (mutable execution state), and masterPlan.md (user-facing proposal for Orbit review). Every step is one component/feature; TDD rhythm (test, verify fail, implement, verify pass, commit) lives in its progress items. Consumes discovery.md from exploration phase. Make sure to use this skill whenever the user says discovery is done, exploration is finished, discovery.md is ready, or asks to write/create/draft the implementation plan — even if they don't mention plan.json or masterPlan.md by name. Also use when the user references completed exploration findings, blast radius analysis, or consumer mappings and wants them converted into actionable steps. Do NOT use when: the user says 'just do it' or 'no plan', resuming or executing an existing plan, during exploration or brainstorming (discovery not yet complete), debugging, or code review.
tools
End-to-end webapp testing with Playwright MCP integration. Use when: writing Playwright tests, E2E testing, browser testing, webapp testing, visual regression testing, accessibility testing with axe-core, testing user flows through a web UI, verifying frontend behavior in a real browser. Integrates with test-driven-development skill for test-first browser tests and engineering-discipline for verification. Do NOT use when: unit tests only (no browser UI involved), API tests without UI, mobile native testing (use react-native-mobile), testing CLI tools, or writing backend-only integration tests.
development
Test-Driven Development workflow enforcing red-green-refactor cycles. Use when writing new features, adding behavior, or implementing functions where tests should drive design. Requires explicit test-first prompting because Claude naturally writes implementation first. Integrates with writing-plans (TDD rhythm in Progress items) and engineering-discipline (verification). Do NOT use when: fixing a bug in existing tested code (use systematic-debugging), writing tests for existing untested code (characterization tests are a different workflow), refactoring without behavior change (use refactoring), or the project has no test infrastructure.
development
Use when encountering any bug, test failure, or unexpected behavior. Enforces root cause investigation before fixes. Four phases: investigate, analyze patterns, form hypotheses, implement. Prevents guess-and-check thrashing. Use ESPECIALLY when under pressure or when 'just one quick fix' seems obvious. Do NOT use for: learning unfamiliar APIs (use exploration), performance optimization without a specific regression, or code review without a reported bug.