refactoring-csharp
Skill169 starsChanged 56 days agoMITView on GitHub
Rename and refactor C# symbols in a .NET solution or multi-solution monorepo with a one-shot Roslyn CLI. Use when the user asks to rename a symbol, preview impact, update references across a solution, or refactor shared projects across several solutions.
In this repository23 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- agentic-readinessSkill
- bug-fix-protocolSkill
- clipboardSkill
- code-that-fits-in-your-headSkill
- fetch-url-as-markdownSkill
- fpf-problem-solvingSkill
- hooks-managementSkill
- installing-cli-toolsSkill
- investigating-repository-historySkill
- maintaining-macos-healthSkill
- maintaining-windows-healthSkill
- mcp-managementSkill
- plan-modeSkill
- plugins-managementSkill
- prompt-engineeringSkill
- repo-activity-summarySkill
- semantic-scholar-deepSkill
- settings-managementSkill
- skills-managementSkill
- ubiquitous-languageSkill
- windows-qa-engineerSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
20 rules. About 0 are common, 10 are distinctive, and 10 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈10
Distinctive · estimate
This author's own choices. Worth a look.
10
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 27
If the skill was installed by install.sh, prefer the prebuilt CLI:
- Distinctive: line 39
When invoked from outside the skill directory, use an absolute project path:
- Very specific: line 74
Use rg -n to locate the symbol and copy the 1-based line number directly.
- Very specific: line 75
Call rename-symbol once without the dryRun argument for normal rename requests.
- Distinctive: line 77
Do not run a dry run just because the tool supports it.
- Very specific: line 82
Use directory mode only when a repository contains multiple .sln/.slnx files or shared projects that are not all present in one normal …
- Very specific: line 86
When solution_path is a directory:
- Very specific: line 89
Keep file_path as the absolute path to the target source file.
- Very specific: line 97
If solution_path is a directory, the tool scans it recursively, merges discovered .sln, .slnx, and project files into one temporary .slnx, …
- Distinctive: line 99
Prefer one apply call over preview+apply when the user already asked to perform the rename.
- Distinctive: line 101
Do not invent a session or hidden prepare state.
- Very specific: line 102
Do not ask for a column number.
- Distinctive: line 106
If the tool returns a preview, say preview.
- Distinctive: line 107
Keep responses concise and action-oriented.
- Very specific: line 111
Treat these as supported rename targets when the Roslyn symbol is source-backed and CanBeReferencedByName:
- Distinctive: line 124
Do not rename constructors, destructors, static constructors, or indexers.
- Very specific: line 131
If the tool does not return file_move_from_path and file_move_to_path, the symbol rename is still valid, but the file itself was not moved.
- Distinctive: line 138
Use the tool's error codes as actionable guidance:
- Distinctive: line 170
If the file move fields are present, mention them explicitly.
- Distinctive: line 171
If the tool returned an error code, echo the code and the human-readable reason.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Refactoring C# Symbols
This skill ships a Roslyn-based C# rename CLI in src/. It is intentionally one-shot and
stateless: one call resolves the target, validates the request, and returns either a preview
or an applied rename. There is no public prepare step.
Contents
- Canonical CLI
- Contract
- How To Use It
- Monorepo Directory Mode
- Important Behavioral Rules
- Supported Targets
- File Rename Nuance
- Error Handling
- Success Criteria
- Recommended Output Style
Canonical CLI
If the skill was installed by install.sh, prefer the prebuilt CLI:
bin/csharp-refactor rename-symbol <sln|slnx|directory> <file> <line> <oldName> <newName> [dryRun=false|true]Otherwise run the bundled source CLI from the skill directory:
dotnet run --project src/CSharpRefactoring.Cli -- rename-symbol <sln|slnx|directory> <file> <line> <oldName> <newName> [dryRun=false|true]When invoked from outside the skill directory, use an absolute project path:
/<skill-dir>/bin/csharp-refactor rename-symbol <sln|slnx|directory> <file> <line> <oldName> <newName> [dryRun=false|true]
# or, if no prebuilt binary is installed:
dotnet run --project /path/to/refactoring-csharp/src/CSharpRefactoring.Cli -- rename-symbol <sln|slnx|directory> <file> <line> <oldName> <newName> [dryRun=false|true]The tool project may create normal bin/ and obj/ directories under the skill. That is
expected and useful: it lets repeated runs reuse the .NET build cache instead of rebuilding
the CLI from scratch.
The target solution is not redirected to a temporary build output. The CLI opens the solution
from the solution directory and lets Roslyn/MSBuild use the target project's normal build
cache (obj/, bin/, or the repository's configured artifacts layout). This is intentional:
it avoids creating a second cache tree for the project being refactored and lets repeated
renames benefit from the project's existing MSBuild/Roslyn design-time build cache.
Contract
| Field | Required | Default | Notes |
solution_path | yes | - | Absolute path to the .sln/.slnx file, or a repository directory for monorepo-wide refactoring. |
file_path | yes | - | Absolute path to a file inside the solution. |
line_number | yes | - | 1-based line number. Use the value reported by rg -n. |
old_name | yes | - | Exact current identifier on that line. This is the anchor. |
new_name | yes | - | Must be a valid C# identifier. |
dry_run | no | false | Apply changes by default. Preview only when explicitly set to true. |
rename_overloads | no | false | Keep overloads unchanged by default. |
rename_in_strings | no | false | String literals stay untouched by default. |
rename_in_comments | no | true | Comments are renamed by default. |
rename_file | no | true | Safe file move for supported named types. Never recreate the file as delete+add. |
How To Use It
- Use
rg -nto locate the symbol and copy the 1-based line number directly. - Call
rename-symbolonce without thedryRunargument for normal rename requests. This applies the rename. - Use
dryRun=trueonly when the user explicitly asks for preview, when the target is ambiguous, or when the rename is unusually broad/risky and applying immediately would be irresponsible. The CLI also acceptstrue,--dry-run,dryRun=false,false, and--no-dry-run; invalid values fail fast and must never silently apply. - Do not run a dry run just because the tool supports it. The tool loads the solution on every call, so preview+apply doubles the cost on large projects.
- Summarize the result by reporting the original name, new name, changed document count, total text changes, changed files, and any file move.
Monorepo Directory Mode
Use directory mode only when a repository contains multiple .sln/.slnx files or shared
projects that are not all present in one normal solution. For ordinary repositories, pass the
specific solution file because it is faster and avoids scanning unrelated projects.
When solution_path is a directory:
- Pass the repository or workspace root as
solution_path. - Keep
file_pathas the absolute path to the target source file. - The tool recursively discovers
.sln,.slnx, and supported project files under the directory. - It merges them into one temporary
.slnx, opens that aggregate solution, performs the rename, and deletes the temporary solution directory before returning. - The temporary aggregate solution lives outside the target repository; source files and normal project build caches remain in their original locations.
Important Behavioral Rules
- The tool is stateless. It loads the solution on every call.
- If
solution_pathis a directory, the tool scans it recursively, merges discovered.sln,.slnx, and project files into one temporary.slnx, opens that solution, runs the rename, and deletes the temporary solution directory before returning. - A preview does not reserve state. If the workspace changes between preview and apply, rerun the preview.
- Prefer one apply call over preview+apply when the user already asked to perform the rename.
- For a
.sln/.slnxinput, the tool runs Roslyn from the target solution directory. For a directory input, it runs Roslyn from that directory while opening the temporary aggregate solution. In both modes, project files stay in place and use the target project's normal MSBuild outputs. - Do not invent a session or hidden prepare state.
- Do not ask for a column number. The tool resolves from
file_path,line_number, andold_name. old_nameis mandatory because it disambiguates the target when a line contains more than one renameable identifier.- The bundled source requires .NET 10 and restores NuGet packages on first run.
- Let the tool keep its own normal
bin/andobj/cache unless the user explicitly asks for a clean/no-cache run. - If the tool returns a preview, say preview. If it returns applied changes, say applied.
- Keep responses concise and action-oriented. Tell the user what changed and whether a file move happened.
Supported Targets
Treat these as supported rename targets when the Roslyn symbol is source-backed and
CanBeReferencedByName:
NamedTypeMethodPropertyFieldEventParameterLocalTypeParameterNamespace
Do not rename constructors, destructors, static constructors, or indexers.
File Rename Nuance
rename_file=true is a convenience default, but it only produces a real safe move when the
symbol is a single-declaration named type and the file stem matches the current type name.
If the tool does not return file_move_from_path and file_move_to_path, the symbol rename is still valid,
but the file itself was not moved. Do not claim a file rename happened unless the tool reports it.
This is intentionally conservative so git sees a tracked rename instead of a delete+add pair.
Error Handling
Use the tool's error codes as actionable guidance:
| Error code | Meaning | What to do |
invalid_solution_path | Solution path is missing, does not exist, or is neither .sln/.slnx nor a directory. | Ask for a real solution path or repository directory. |
invalid_file_path | File path is missing or not present on disk. | Ask for the correct file path. |
file_not_in_solution | The file is not part of the loaded solution. | Ask for the correct file or solution. |
invalid_line_number | Line number is outside file bounds or not 1-based. | Ask for the correct line. |
invalid_old_name | old_name was empty or whitespace. | Ask for the exact current name. |
old_name_not_found_on_line | No renameable symbol with that name exists on the line. | Ask for a better line or file. |
ambiguous_old_name_on_line | More than one renameable symbol matches that name on the line. | Narrow the target or use a different line. |
unsupported_symbol_kind | Roslyn found a symbol, but this kind is not renameable here. | Move to a supported symbol kind. |
symbol_not_in_source | The symbol is not declared in source. | Pick a source-backed target. |
invalid_new_name | new_name is not a valid C# identifier. | Propose a valid identifier. |
same_name | New name equals the current name. | Ask for a different name. |
no_changes | Roslyn produced no text edits. | Re-check the target or the new name. |
apply_failed | Workspace apply failed. | Treat as a runtime failure and retry only if the state is unchanged. |
operation_timeout | The rename timed out. | Retry with a larger timeout or a narrower target. |
Success Criteria
A rename workflow is complete when:
- The target was resolved from
line_number+old_name. - The user approved the rename, or explicitly requested a dry run only.
- The tool returned changed documents, total text changes, and any file move details.
- The final answer makes the applied scope clear enough for the user to trust the change.
Recommended Output Style
- For previews, say what would change and that nothing was applied.
- For applied changes, say what changed and whether the file was moved.
- If the file move fields are present, mention them explicitly.
- If the tool returned an error code, echo the code and the human-readable reason.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

