Agent Skills: Safe Refactor Skill

Perform safe code refactoring with reference checking and validation. Uses Julie's rename_symbol for workspace-wide renames and fuzzy_replace for precise edits. Activates when user wants to refactor, rename, or safely modify code.

UncategorizedID: anortham/julie/safe-refactor

Skill Files

Browse the full folder contents for safe-refactor.

Download Skill

Loading file tree…

skills/safe-refactor/SKILL.md

Skill Metadata

Name
safe-refactor
Description
Perform safe code refactoring with reference checking and validation. Uses Julie's rename_symbol for workspace-wide renames and fuzzy_replace for precise edits. Activates when user wants to refactor, rename, or safely modify code.

Safe Refactor Skill

Purpose

Perform safe, validated code refactoring using Julie's intelligence to prevent breaking changes. This skill combines reference checking, workspace-wide renames, and fuzzy matching edits to modify code confidently.

When to Activate

Use when the user:

  • Wants to rename: "rename this function", "change variable name"
  • Needs to refactor: "extract this code", "refactor this class"
  • Modifies code safely: "update this API", "change this interface"
  • Reorganizes code: "move this to another file", "split this class"

Julie's Refactoring Tools

πŸ”„ Workspace-Wide Renaming

rename_symbol - AST-aware symbol renaming

Renames symbols across entire workspace
- Checks all references first
- AST-aware (understands code structure)
- Safe multi-file updates
- Preserves code semantics

Use when: Renaming classes, functions, variables, types

✏️ Precise Code Editing

fuzzy_replace - Diff-match-patch fuzzy matching

Professional text replacement with fuzzy tolerance
- Handles whitespace variations
- Tolerates minor differences
- Character-based (UTF-8 safe)
- Validation before commit

Use when: Targeted edits, method bodies, imports, specific code sections

πŸ” Safety Checks

fast_refs - Find all references

Critical for impact analysis
- See all usage points
- Verify scope of change
- Identify breaking changes

fast_goto - Find definitions

Verify symbol exists before rename
Understand current implementation

get_symbols - Structure validation

Verify file structure before/after edits
Ensure no symbols lost

Orchestration Strategy

Pattern 1: Safe Symbol Rename

Goal: Rename across entire workspace

1. fast_refs({ symbol: "oldName" }) β†’ Check all references
2. Review impact (how many files affected?)
3. Ask user confirmation if >10 files
4. rename_symbol({ old_name: "oldName", new_name: "newName" })
5. Verify completion

Pattern 2: Targeted Code Edit

Goal: Modify specific code section

1. get_symbols to understand structure
2. Read target section
3. fuzzy_replace with old/new strings
4. Verify edit succeeded
5. Run tests if available

Pattern 3: Extract Function

Goal: Extract code to new function

1. Identify code to extract
2. fast_refs to check variable usage
3. Create new function with fuzzy_replace
4. Replace original code with call
5. Verify both edits

Pattern 4: Refactor with Validation

Goal: Large refactoring with safety

1. get_symbols(mode="structure") β†’ Baseline
2. Perform edits (rename_symbol + fuzzy_replace)
3. get_symbols again β†’ Verify structure
4. fast_refs on modified symbols β†’ Check usage
5. Run tests β†’ Confirm no breakage

Example Refactoring Sessions

Example 1: Rename Function Safely

User: "Rename getUserData to fetchUserProfile"

Skill activates β†’ Safe rename process

Step 1: Check References
β†’ fast_refs({ symbol: "getUserData" })

References found (8 locations):
- src/services/user.ts (definition)
- src/api/users.ts (3 calls)
- src/components/Profile.tsx (2 calls)
- src/hooks/useUser.ts (1 call)
- tests/user.test.ts (1 call)

Step 2: Confirm Impact
β†’ "Found 8 references across 5 files. This is a safe rename.
   Proceeding with workspace-wide rename."

Step 3: Execute Rename
β†’ rename_symbol({
    old_name: "getUserData",
    new_name: "fetchUserProfile"
  })

Step 4: Verify
β†’ fast_refs({ symbol: "fetchUserProfile" })
β†’ Confirm all 8 references updated

Result: "βœ… Renamed getUserData β†’ fetchUserProfile across 5 files (8 references)"

Example 2: Refactor with Fuzzy Replace

User: "Change this error handling to use our new logger"

Current code:
console.error('Failed to load user:', error);
throw error;

Step 1: Read Context
β†’ get_symbols to see function structure

Step 2: Prepare Replacement
Old (with fuzzy tolerance):
console.error('Failed to load user:', error);

New:
logger.error('Failed to load user', { error });
throw new UserLoadError('Failed to load user', error);

Step 3: Execute Fuzzy Replace
β†’ fuzzy_replace({
    file_path: "src/services/user.ts",
    old_string: "console.error('Failed to load user:', error);\nthrow error;",
    new_string: "logger.error('Failed to load user', { error });\nthrow new UserLoadError('Failed to load user', error);",
    similarity_threshold: 0.8
  })

Step 4: Verify
β†’ Read updated section
β†’ Confirm change applied correctly

Result: "βœ… Updated error handling to use logger.error and UserLoadError"

Example 3: Extract to New Function

User: "Extract this validation logic to a separate function"

Current code in saveUser():
if (!email || !email.includes('@')) {
  throw new Error('Invalid email');
}
if (!password || password.length < 8) {
  throw new Error('Password too short');
}

Step 1: Check Variable Usage
β†’ fast_refs on 'email', 'password'
β†’ Confirm local to function

Step 2: Create New Function
β†’ fuzzy_replace to add:
function validateUserInput(email: string, password: string) {
  if (!email || !email.includes('@')) {
    throw new Error('Invalid email');
  }
  if (!password || password.length < 8) {
    throw new Error('Password too short');
  }
}

Step 3: Replace Original Code
β†’ fuzzy_replace validation block with:
validateUserInput(email, password);

Step 4: Verify
β†’ get_symbols β†’ See new function added
β†’ Read both locations β†’ Verify correctness

Result: "βœ… Extracted validation logic to validateUserInput()"

Safety Checklist

Before any refactoring:

βœ… Pre-Refactor Checks

  • [ ] Check references with fast_refs
  • [ ] Understand current structure with get_symbols
  • [ ] Identify impact scope (how many files?)
  • [ ] Confirm no active PRs on affected files
  • [ ] Consider backward compatibility needs

βœ… During Refactor

  • [ ] Use appropriate tool (rename_symbol vs fuzzy_replace)
  • [ ] Provide clear old/new strings for fuzzy_replace
  • [ ] Use reasonable similarity threshold (0.75-0.85)
  • [ ] Verify each step before proceeding

βœ… Post-Refactor Validation

  • [ ] Verify edits applied correctly
  • [ ] Check symbol structure unchanged (unless intended)
  • [ ] Confirm all references updated
  • [ ] Run tests if available
  • [ ] Review git diff for unexpected changes

Tool Selection Guide

Use rename_symbol when:

  • Renaming classes, functions, methods, variables
  • Need workspace-wide consistency
  • AST-aware understanding required
  • Multi-file impact expected

Use fuzzy_replace when:

  • Modifying method bodies
  • Updating imports/exports
  • Changing specific code sections
  • Tolerance for whitespace variations needed

Use Edit tool when:

  • Simple, exact string replacement
  • Single file, small change
  • No fuzzy matching needed
  • Direct line-based editing

Error Handling

fuzzy_replace Validation Errors

Error: "Similarity 0.65 below threshold 0.75"
β†’ Check old_string matches current code
β†’ Adjust threshold or fix old_string
β†’ Verify no unexpected changes in file

rename_symbol Failures

Error: "Symbol not found: oldName"
β†’ Verify symbol exists with fast_goto
β†’ Check spelling and casing
β†’ Ensure symbol is in scope

Reference Conflicts

Warning: "Found 47 references across 15 files"
β†’ Confirm with user before proceeding
β†’ Consider splitting into smaller renames
β†’ Verify scope is correct

Integration with Other Skills

With Sherpa Workflows

[Refactor Workflow - Phase 1: Tests First]
β†’ Ensure test coverage exists
β†’ safe-refactor skill: Perform refactoring
[Phase 2: Refactor Code]
β†’ Use rename_symbol and fuzzy_replace
[Phase 3: Verify]
β†’ Run tests, check references

With Goldfish Memory

[Before refactoring]
β†’ Goldfish: checkpoint({ description: "Pre-refactor state" })
[Perform refactoring]
β†’ safe-refactor skill: Execute changes
[After refactoring]
β†’ Goldfish: checkpoint({ description: "Refactored X to Y, 8 files updated" })

Key Behaviors

βœ… DO

  • Always check references before renaming
  • Use fuzzy_replace for tolerance to whitespace
  • Verify edits succeeded
  • Run tests after significant changes
  • Provide clear descriptions of changes
  • Ask for confirmation on large-scope changes

❌ DON'T

  • Rename without checking references first
  • Use exact string matching when fuzzy is better
  • Skip post-refactor verification
  • Ignore test failures after refactoring
  • Make changes without understanding impact
  • Proceed with risky renames without user consent

Success Criteria

This skill succeeds when:

  • Code refactored without breaking changes
  • All references updated consistently
  • Tests still pass (if applicable)
  • Changes are semantically correct
  • User confident in the safety of edits

Performance

  • rename_symbol: ~200-500ms (depending on workspace size)
  • fuzzy_replace: ~50-100ms per edit
  • fast_refs: ~50ms for reference checking
  • get_symbols: ~100ms for structure validation

Total refactoring session: ~1-2 seconds + test run time


Remember: Safe refactoring is about checking references, understanding impact, and verifying changes. Use Julie's tools to make confident edits without breaking your codebase!