Safe refactoring operations using LSP for precise symbol resolution. Supports rename, extract function/method, and move symbol operations with automatic reference updates.
This skill inherits all available tools. When active, it can use any tool Claude has access to.
Skill(foundry:sdd-refactor) provides LSP-powered refactoring with safety checks. It uses findReferences to understand impact before making changes, performs batch edits, and verifies correctness.
Core capabilities:
IMPORTANT: This skill uses Claude Code's built-in LSP tools for precise refactoring. If LSP returns no results for the target language, fall back to Grep-based patterns.
This skill integrates with the Spec-Driven Development workflow:
sdd-plan --> sdd-refactor (for planned refactoring tasks) --> sdd-update --> sdd-fidelity-review
Can also be used standalone for ad-hoc refactoring outside of specs.
Use Skill(foundry:sdd-refactor) for:
Do NOT use for:
This skill uses Claude Code's built-in LSP tools directly:
| Tool | Purpose |
|---|---|
findReferences | Find all usages of a symbol |
goToDefinition | Navigate to symbol definition |
documentSymbol | Get file structure/symbol outline |
For spec integration, use foundry-mcp:
| Router | Actions | Purpose |
|---|---|---|
task | update-status, complete | Track refactoring task progress |
journal | add | Document refactoring decisions |
Gather information about what to refactor:
User provides:
Validate target exists with LSP:
definition = goToDefinition(file="src/module.py", symbol="OldClassName", line=10)
if definition found:
Proceed to impact analysis
else:
Ask user to verify symbol name and location
Fallback if LSP unavailable:
Use Grep to verify symbol exists:
Grep(pattern="class OldClassName", path="src/")
NEVER refactor without understanding impact first.
# Get all references to the symbol
references = findReferences(file="src/module.py", symbol="OldClassName", line=10, character=6)
# Analyze results:
- Total reference count
- Unique files affected
- Reference types (import, call, type annotation, assignment)
- Test files vs production files
Present to user before proceeding:
## Refactoring Impact: Rename OldClassName -> NewClassName
**Total References:** 47 across 12 files
**By Category:**
- Imports: 12 files
- Class instantiation: 8 locations
- Type annotations: 15 locations
- Inheritance: 2 locations
**Files Affected:**
- src/auth/service.py (8 refs)
- src/api/handlers.py (12 refs)
- tests/test_auth.py (15 refs)
- ... (9 more files)
**Risk Assessment:** MEDIUM
- All references in controlled codebase
- Good test coverage (15 test refs)
Proceed? [Execute] [Dry Run] [Cancel]
If LSP unavailable:
Use Grep to find references:
Grep(pattern="OldClassName", path="src/", output_mode="content")
WARNING: Grep-based analysis may include false positives (comments, strings).
Review each match before proceeding.
With LSP:
findReferencesfindReferences(file="src/module.py", symbol="NewClassName")
# Should return same count as before
Without LSP (Manual):
documentSymbol(file="src/module.py")
# Confirm new function appears in symbols
findReferences(file="new/location.py", symbol="MovedSymbol")
# All references should resolve
references = findReferences(file="src/utils.py", symbol="unused_function")
if references.count == 0:
Safe to remove
elif references.count == 1 and reference is definition:
Safe to remove (only self-reference)
else:
NOT safe - has usages
After any refactoring:
Structural verification (LSP):
documentSymbol(file="src/module.py")
# Verify expected structure preserved
Reference verification (LSP):
findReferences(file="src/module.py", symbol="NewName")
# Verify all references resolve
Run affected tests:
Skill(foundry:run-tests) "Run tests for affected files"
If refactoring is part of a spec task:
mcp__plugin_foundry_foundry-mcp__task action="complete" spec_id="{spec-id}" task_id="{task-id}" completion_notes="Renamed OldClassName to NewClassName across 12 files. All tests passing."
For significant refactors, add journal entry:
mcp__plugin_foundry_foundry-mcp__journal action="add" spec_id="{spec-id}" title="Refactoring: OldClassName -> NewClassName" content="Renamed class for clarity. 47 references updated across 12 files. No functional changes." entry_type="decision"
Before using LSP-enhanced workflow, verify availability:
# Try to get symbols from target file
symbols = documentSymbol(file="target_file.py")
if symbols returned successfully:
Use LSP-enhanced workflow
else:
Fall back to Grep-based workflow
Fallback triggers:
| Scope | Approach |
|---|---|
| Single file, <10 refs | Direct refactoring |
| Cross-file, <50 refs | Batch with verification |
| 50-100 refs | Split into incremental changes |
| >100 refs | Create spec for tracking, phase the work |
Rename class:
Skill(foundry:sdd-refactor) "Rename AuthService to AuthenticationService in src/auth/service.py"
Extract method:
Skill(foundry:sdd-refactor) "Extract lines 45-67 in src/handlers.py into new method validate_request"
Move function:
Skill(foundry:sdd-refactor) "Move helper_function from src/utils.py to src/helpers/common.py"
Dead code cleanup:
Skill(foundry:sdd-refactor) "Find and remove unused functions in src/legacy/"
Rename with spec context:
Skill(foundry:sdd-refactor) "Complete task-2-3: Rename UserDTO to UserResponse as specified"