lsp-refactor — Claude Code skill: what it does, how to install
Runs a guarded refactoring pipeline with blast-radius checks, in-memory edit previews, disk application, build verification, and targeted tests.
npx skills add blackwell-systems/agent-lsp --skill lsp-refactor -a claude-codeWhat lsp-refactor does
The skill bundles four phases into a single continuous sequence. First, it computes the blast radius through mcp__lsp__blast_radius before touching any code. If the change impacts more than 20 call sites, execution stops and asks for manual confirmation. This prevents accidental widespread damage across the codebase.
Once approved, the skill tests edits in memory with preview_edit or simulate_chain against compiler diagnostics. It writes changes to disk only when net_delta introduces no new diagnostic errors. It then triggers the build and runs test suites that touch the modified code.
Running this workflow requires the agent-lsp MCP server with an active referencesProvider. The skill forbids mcp__lsp__rename_symbol by design. Edits apply either via AST replacement using mcp__lsp__replace_symbol_body or standard buffer edits.
What it helps with
- calculate refactoring blast radius before modifying any files
- simulate multi-file edits in memory to compare diagnostic diffs
- replace function bodies cleanly without manual line-offset calculations
- run only test suites linked to modified symbols
Example prompts for the agent
- Refactor
codec.Encode: add a second parametertimeout time.Duration - Update
internal/lsp/client.go: rename the function toParseConfigV2 - Safely refactor
Buffer.Resetand run affected tests
How to install lsp-refactor
1Skills CLI (Vercel)
npx skills add blackwell-systems/agent-lsp --skill lsp-refactor -a claude-code2Manually: put the files in place
~/.claude/skills/lsp-refactor/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/lsp-refactor/
1Skills CLI (Vercel)
npx skills add blackwell-systems/agent-lsp --skill lsp-refactor -a codex2Manually: put the files in place
.agents/skills/lsp-refactor/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add blackwell-systems/agent-lsp --skill lsp-refactor -a cursor2Manually: put the files in place
.cursor/skills/lsp-refactor/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install blackwell-systems/agent-lsp lsp-refactor2Manually: put the files in place
.github/skills/lsp-refactor/SKILL.md1Skills CLI (Vercel)
npx skills add blackwell-systems/agent-lsp --skill lsp-refactor -a gemini-cli2Platform CLI
gemini skills install https://github.com/blackwell-systems/agent-lsp --path skills/lsp-refactorManually: put the files in place
.devin/skills/lsp-refactor/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add blackwell-systems/agent-lsp --skill lsp-refactor -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about lsp-refactor
How do I install lsp-refactor in Claude Code?
Run npx skills add blackwell-systems/agent-lsp --skill lsp-refactor -a claude-code.
What does lsp-refactor do?
It sequences impact analysis, memory-based edit simulation, disk writes, build checks, and relevant test execution into one automated run.
What prerequisites does lsp-refactor need?
It requires the agent-lsp MCP server with an underlying language server that supports referencesProvider.
Source text
SKILL.md · MIT
---
name: lsp-refactor
description: End-to-end safe refactor workflow — blast-radius analysis, speculative preview, apply to disk, verify build, run affected tests. Inlines lsp-impact + lsp-safe-edit + lsp-verify + lsp-test-correlation into one coordinated sequence.
argument-hint: "[symbol-or-file] [intent]"
user-invocable: true
allowed-tools: mcp__lsp__blast_radius mcp__lsp__preview_edit mcp__lsp__simulate_chain mcp__lsp__get_diagnostics mcp__lsp__run_build mcp__lsp__run_tests mcp__lsp__get_tests_for_file mcp__lsp__apply_edit mcp__lsp__replace_symbol_body mcp__lsp__open_document mcp__lsp__format_document Edit Write
license: MIT
compatibility: Requires the agent-lsp MCP server (github.com/blackwell-systems/agent-lsp)
metadata:
required-capabilities: referencesProvider
optional-capabilities: documentFormattingProvider
tool_permissions:
phases:
blast_radius:
description: "Phase 1: analyze impact before any edits"
allowed:
- "mcp__lsp__blast_radius"
- "mcp__lsp__go_to_symbol"
- "mcp__lsp__find_references"
forbidden:
- "mcp__lsp__apply_edit"
- "mcp__lsp__simulate_*"
- "Edit"
- "Write"
speculative_preview:
description: "Phase 2: simulate edits in memory, compare diagnostics"
allowed:
- "mcp__lsp__open_document"
- "mcp__lsp__get_diagnostics"
- "mcp__lsp__preview_edit"
- "mcp__lsp__simulate_chain"
forbidden:
- "mcp__lsp__apply_edit"
- "Edit"
- "Write"
apply:
description: "Phase 3: write changes to disk and format"
allowed:
- "mcp__lsp__apply_edit"
- "mcp__lsp__format_document"
- "Edit"
- "Write"
forbidden:
- "mcp__lsp__simulate_*"
- "mcp__lsp__rename_symbol"
build_verification:
description: "Phase 4: check diagnostics and run the build"
allowed:
- "mcp__lsp__get_diagnostics"
- "mcp__lsp__run_build"
forbidden:
- "mcp__lsp__apply_edit"
- "Edit"
- "Write"
test_execution:
description: "Phase 5: find and run affected tests"
allowed:
- "mcp__lsp__get_tests_for_file"
- "mcp__lsp__run_tests"
forbidden:
- "mcp__lsp__apply_edit"
- "Edit"
- "Write"
global_forbidden:
- "mcp__lsp__rename_symbol" # refactor uses edit, not rename
---
> Requires the agent-lsp MCP server.
# lsp-refactor
End-to-end safe refactor workflow. Sequences blast-radius analysis, speculative
preview, disk apply, build verification, and targeted test execution in one
coordinated pass.
**This skill does NOT replace lsp-safe-edit or lsp-impact.**
- `lsp-safe-edit` wraps a single edit with before/after diagnostic comparison —
use it when you need to make one targeted change with careful error diffing.
- `lsp-impact` is read-only blast-radius analysis — use it when you want to
understand scope before deciding whether to proceed.
- `lsp-refactor` sequences ALL four workflows (lsp-impact → lsp-safe-edit →
lsp-verify → lsp-test-correlation) in order. Use it when you know your target
and intent up front and want the complete workflow without switching skills.
---
## Input
- **target**: symbol name in dot notation (e.g. `"codec.Encode"`, `"Buffer.Reset"`)
OR file path (e.g. `"internal/lsp/client.go"`)
- **intent**: description of the change to make (e.g. "rename to ParseConfigV2",
"add a second parameter `timeout time.Duration`")
- **workspace_root**: absolute path to the workspace root
---
## Phase 1 — Blast-Radius Analysis (inlined from lsp-impact)
**This phase is mandatory. Do not skip it, even for "small" refactors.**
Call `mcp__lsp__blast_radius` with `changed_files` set to the file
containing the target symbol. If the user provided a file path directly, use it.
If the user provided a symbol name, resolve the file first (e.g. via
`mcp__lsp__go_to_symbol`).
```
mcp__lsp__blast_radius({
"changed_files": ["/abs/path/to/file"],
"include_transitive": false
})
```
Returns:
- `affected_symbols` — exported symbols with reference counts
- `test_callers` — test files and enclosing test function names
- `non_test_callers` — production call sites
**Display:**
- Affected symbol count
- Test callers (each with enclosing test function name)
- Non-test callers (each with file:line)
- Total reference count
**High blast-radius gate:** If the total reference count exceeds 20, STOP and
ask the user to confirm before continuing:
```
High blast radius: N callers found. Proceed with refactor? [y/n]
```
If the user answers "n", abort. Do not proceed to Phase 2.
---
## Phase 2 — Speculative Preview (inlined from lsp-safe-edit)
Only reached if Phase 1 blast radius is acceptable (≤ 20 callers, or user confirmed).
### 2a — Open file and capture baseline diagnostics
```
mcp__lsp__open_document({ "file_path": "/abs/path/to/file", "language_id": "go" })
mcp__lsp__get_diagnostics({ "file_path": "/abs/path/to/file" })
```
Store baseline diagnostics as BEFORE.
### 2b — Speculative simulation
For a **single-file change**: use `preview_edit`:
```
mcp__lsp__preview_edit({
"file_path": "/abs/path/to/file",
"start_line": <N>,
"start_column": <col>,
"end_line": <N>,
"end_column": <col>,
"new_text": "<replacement text>"
})
```
For a **multi-file change** (e.g. rename + call site updates): use `simulate_chain`:
```
mcp__lsp__simulate_chain({
"workspace_root": "/abs/path/to/workspace",
"language": "go",
"edits": [
{
"file_path": "/abs/path/to/file.go",
"start_line": <N>, "start_column": <col>,
"end_line": <N>, "end_column": <col>,
"new_text": "<replacement>"
}
// additional dependent edits ...
]
})
```
### 2c — Evaluate simulation result
Display the speculative result using the Diagnostic Diff Output Format from
[references/patterns.md](references/patterns.md).
**Decision:**
| `net_delta` | Action |
|-------------|--------|
| ≤ 0 | Safe. Proceed to Phase 3. |
| > 0 | **Abort.** Report introduced errors. Do NOT apply to disk. |
If `net_delta > 0`, stop and show the full list of errors the simulation
introduced. Do not proceed to Phase 3.
---
## Phase 3 — Apply to Disk
Only reached if Phase 2 `net_delta <= 0`.
Apply the change using the Edit or Write tool. When the edit targets a complete
function or method body, `mcp__lsp__replace_symbol_body` is an alternative that
resolves the symbol by name and replaces its full range without position math:
```
mcp__lsp__replace_symbol_body({
"file_path": "/abs/path/to/file",
"symbol_path": "Package.Function",
"new_body": "func Function() error {\n\treturn nil\n}"
})
```
For edits computed by simulation, `mcp__lsp__apply_edit` may be used directly if
the simulation returned an edit object:
```
Edit(file_path: "/abs/path/to/file", old_string: "...", new_string: "...")
```
For multi-file changes, apply each file's edits before moving to Phase 4.
If any individual apply fails, stop and report before applying remaining files.
After applying, format the changed file(s):
```
mcp__lsp__format_document({ "file_path": "/abs/path/to/file" })
```
Apply the returned `TextEdit[]` via `mcp__lsp__apply_edit` if non-empty.
---
## Phase 4 — Build Verification (inlined from lsp-verify)
Run in this order — LSP diagnostics first, then the compiler build:
```
mcp__lsp__get_diagnostics({ "file_path": "/abs/path/to/file" })
mcp__lsp__run_build({ "workspace_root": "/abs/path/to/workspace" })
```
**Decision:**
| Result | Action |
|--------|--------|
| Diagnostics clean, build passes | Proceed to Phase 5. |
| Diagnostics show new errors | Display errors and stop. Do not proceed to Phase 5. |
| Build fails | Display build output and stop. Do not proceed to Phase 5. |
If build fails, report the full build error output and stop. Test execution
is skipped until build passes.
---
## Phase 5 — Run Affected Tests (inlined from lsp-test-correlation)
For each file changed in Phase 3, find correlated test files:
```
mcp__lsp__get_tests_for_file({ "file_path": "/abs/path/to/changed/file" })
```
Deduplicate the resulting test files if multiple source files were changed.
Run only the correlated test files:
```
mcp__lsp__run_tests({ "workspace_root": "/abs/path/to/workspace", "test_files": [...] })
```
**If no correlated test files are found:** note "No test correlation found —
run full suite manually to confirm." Do not attempt to run `./...` automatically.
---
## Abort Conditions
The following conditions abort the workflow immediately. Each abort displays the
relevant output before stopping.
1. **Phase 1:** blast radius > 20 callers AND user does not confirm → abort
2. **Phase 2:** `net_delta > 0` (simulation introduced errors) → abort, show errors
3. **Phase 4:** build fails → abort, show build output
4. **Any phase:** LSP tool returns an unexpected error → abort, report tool output verbatim
---
## Output Format
After completing all phases, produce this structured report:
```
## lsp-refactor Complete
### Phase 1 — Blast Radius
Affected symbols: N
Test callers: M (list each with enclosing test function)
Non-test callers: K
### Phase 2 — Speculative Preview
[Diagnostic Diff Output Format from patterns.md]
net_delta: 0 → safe to apply
### Phase 3 — Applied
Files changed: [list]
### Phase 4 — Build Verification
Diagnostics: N errors (0 new)
Build: PASS
### Phase 5 — Test Results
Test files run: [list]
Result: PASS / FAIL
```
If the workflow aborted at a phase, report only the phases completed and the
abort reason:
```
## lsp-refactor Aborted at Phase 2
### Phase 1 — Blast Radius
...
### Phase 2 — Speculative Preview
ABORTED: net_delta: +2 (errors introduced)
Errors:
- file.go:34 — undefined: NewType
- file.go:51 — cannot use int as string
```
---
## Example
```
Goal: rename exported function ParseConfig → ParseConfigV2 in pkg/config
Phase 1 — Blast Radius
blast_radius(changed_files=["pkg/config/parser.go"])
→ affected_symbols: 1 (ParseConfig)
→ non_test_callers: 3 (cmd/main.go, internal/app.go, internal/loader.go)
→ test_callers: 1 (pkg/config/parser_test.go — TestParseConfig)
→ total references: 4 — within threshold, proceeding
Phase 2 — Speculative Preview
open_document(file_path="pkg/config/parser.go")
get_diagnostics → BEFORE: 0 errors
simulate_chain(edits: [parser.go rename + 3 call-site updates])
→ cumulative_delta: 0 → safe to apply
Phase 3 — Applied
Edit parser.go: func ParseConfig → func ParseConfigV2
Edit cmd/main.go, internal/app.go, internal/loader.go: update call sites
format_document(parser.go)
Phase 4 — Build Verification
get_diagnostics → 0 errors
run_build → success
Phase 5 — Test Results
get_tests_for_file(parser.go) → pkg/config/parser_test.go
run_tests(test_files=["pkg/config/parser_test.go"]) → PASS
## lsp-refactor Complete
...
```
© blackwell-systems · MIT · blackwell-systems/agent-lsp