PluginBench
Skill
Review
Audit score 70

gitnexus-refactoring

abhigyanpatwari/gitnexus

Safely rename, extract, split, and move code across your codebase with automated impact analysis.

What is gitnexus-refactoring?

GitNexus Refactoring automates large-scale code restructuring—renaming symbols, extracting modules, splitting functions, and moving code—while mapping all dependents and verifying changes. Use it when you need to refactor with confidence that all references are updated and no code is left broken.

  • Rename symbols across multiple files with graph-based and text-search confidence levels
  • Map upstream and downstream dependents to understand refactoring impact before making changes
  • Extract modules and split functions while tracking all callers and dependencies
  • Detect and verify changes after refactoring to confirm only expected files were modified
  • Query code relationships with Cypher to find dynamic or string-based references
  • Preview all edits in dry-run mode before applying changes to disk

How to install gitnexus-refactoring

npx skills add https://github.com/abhigyanpatwari/gitnexus --skill gitnexus-refactoring
Prerequisites
  • A Git repository indexed by GitNexus (run `node .gitnexus/run.cjs analyze` if the index is stale)
  • One or more repositories bound via `list_repos {}` before refactoring
  • For linked worktrees, specify the `worktree` parameter in `detect_changes`
Claude Code
Cursor
Windsurf
Cline

How to use gitnexus-refactoring

  1. 1.Run `list_repos {}` to bind your repository and confirm identity (ask if ambiguous with multiple repos)
  2. 2.Use `impact({target: "X", direction: "upstream"})` to map all dependents before refactoring
  3. 3.Call `context({name: "X"})` to see all incoming and outgoing references for the target
  4. 4.Execute the refactoring tool (e.g., `rename()`) with `dry_run: true` and review the preview
  5. 5.Confirm previewed file paths are in the correct repository/worktree
  6. 6.Apply changes with `dry_run: false` once satisfied
  7. 7.Run `detect_changes({scope: "all"})` to verify only expected files changed
  8. 8.Execute tests for affected processes to confirm the refactor is correct

Use cases

Good for
  • Rename a widely-used function and automatically update all 20+ call sites across the codebase
  • Extract a utility module from a monolith and update all imports in dependent services
  • Split a large service into smaller, focused functions with caller updates tracked
  • Move code to a new file and verify no broken references remain
  • Refactor a public API symbol and understand which external processes are affected
Who it's for
  • Backend and full-stack engineers refactoring large codebases
  • Teams managing multi-repository projects with shared symbols
  • Developers performing API migrations or deprecations
  • Anyone needing safe, automated code restructuring with verification

gitnexus-refactoring FAQ

What's the difference between graph edits and text_search edits?

Graph edits use code structure analysis (high confidence) and are safe to apply automatically. Text_search edits find string or dynamic references (lower confidence) and should be reviewed manually before applying.

How do I know which repository will be edited?

Always run `list_repos {}` first to bind identity. Review the previewed `file_path` values in dry-run mode to confirm they belong to the correct repository/worktree before applying changes.

What does 'Index is stale' mean and how do I fix it?

The code index is out of sync with your Git history. Run `node .gitnexus/run.cjs analyze` in the terminal to re-index. Check the `staleness` field—re-analyze only if status is `behind` or `diverged`.

Can I refactor code that appears in multiple repositories?

Yes, but you must explicitly bind the correct repository with the `repo` parameter on every tool call. Always preview in dry-run mode and confirm file paths before applying.

How do I find dynamic or string-based references that rename might miss?

Use `query({search_query: "X"})` to find execution flows involving the target, or write a custom Cypher query with the `cypher` tool to locate specific reference patterns.

Full instructions (SKILL.md)

Source of truth, from abhigyanpatwari/gitnexus.


name: gitnexus-refactoring description: "Use when the user wants to rename, extract, split, move, or restructure code safely. Examples: "Rename this function", "Extract this into a module", "Refactor this class", "Move this to a separate file""

Refactoring with GitNexus

When to Use

  • "Rename this function safely"
  • "Extract this into a module"
  • "Split this service"
  • "Move this to a new file"
  • Any task involving renaming, extracting, splitting, or restructuring code

Bind the repository first

Refactoring writes to disk. rename with dry_run: false edits files in whichever repository was resolved, so binding identity here is a safety gate, not bookkeeping.

Call list_repos {} before the first tool call. With one indexed repository, use the examples below as written. With more than one, pass repo on every call: an omitted repo normally errors, but under an MCP policy with a configured default it resolves to that default silently. If you cannot tell which repository is meant, stop and ask. Never run rename with dry_run: false until the preview in the same bound repository has been reviewed — its returned file_path values show which checkout is about to be written, so read them as a confirmation of identity.

list_repos is paginated, so page with offset: pagination.nextOffset until hasMore is false before concluding a repository is absent.

detect_changes takes worktree when you are editing a linked worktree the MCP server was not launched from; otherwise git diff runs in the wrong checkout and reports nothing changed, which reads as a verified refactor.

Workflow

0. list_repos {}                                  → Bind repo (and worktree)
1. impact({target: "X", direction: "upstream"})  → Map all dependents
2. query({search_query: "X"})                            → Find execution flows involving X
3. context({name: "X"})                           → See all incoming/outgoing refs
4. Plan update order: interfaces → implementations → callers → tests

If "Index is stale" → run node .gitnexus/run.cjs analyze in terminal. Hot-tool staleness names which index answered (branch/lastCommit) and how fresh it is (status). Re-analyze only for behind or diverged — current is identity, unknown is unmeasurable.

Checklists

Rename Symbol

- [ ] list_repos {} — bind repo; explicit repo when >1 indexed, ask if ambiguous
- [ ] rename({symbol_name: "oldName", new_name: "newName", dry_run: true}) — preview all edits
- [ ] Confirm the previewed file paths are in the bound repository/worktree
- [ ] Review graph edits (high confidence) and text_search edits (review carefully)
- [ ] If satisfied: rename({..., dry_run: false}) — apply edits
- [ ] detect_changes() — verify only expected files changed
- [ ] Run tests for affected processes

Extract Module

- [ ] list_repos {} — bind repo; explicit repo when >1 indexed, ask if ambiguous
- [ ] context({name: target}) — see all incoming/outgoing refs
- [ ] impact({target, direction: "upstream"}) — find all external callers
- [ ] Define new module interface
- [ ] Extract code, update imports
- [ ] detect_changes() — verify affected scope
- [ ] Run tests for affected processes

Split Function/Service

- [ ] list_repos {} — bind repo; explicit repo when >1 indexed, ask if ambiguous
- [ ] context({name: target}) — understand all callees
- [ ] Group callees by responsibility
- [ ] impact({target, direction: "upstream"}) — map callers to update
- [ ] Create new functions/services
- [ ] Update callers
- [ ] detect_changes() — verify affected scope
- [ ] Run tests for affected processes

Tools

rename — automated multi-file rename:

rename({symbol_name: "validateUser", new_name: "authenticateUser", repo: "my-app", dry_run: true})
→ 12 edits across 8 files
→ 10 graph edits (high confidence), 2 text_search edits (review)
→ Changes: [{file_path, edits: [{line, old_text, new_text, confidence}]}]

impact — map all dependents first:

impact({target: "validateUser", repo: "my-app", direction: "upstream"})
→ d=1: loginHandler, apiMiddleware, testUtils
→ Affected Processes: LoginFlow, TokenRefresh

detect_changes — verify your changes after refactoring:

detect_changes({scope: "all"})
→ Changed: 8 files, 12 symbols
→ Affected processes: LoginFlow, TokenRefresh
→ Risk: MEDIUM

partial: true (a graph query failed) or truncated: true (the changed-symbol listing was capped) means the result is short of the truth: a short or empty list is not proof that only the expected files changed. Re-run it rather than treat the refactor as verified.

A wrong-worktree zero carries neither flag and is indistinguishable from a clean verification, so confirm the diffed checkout is the one you edited.

cypher — custom reference queries:

MATCH (caller)-[:CodeRelation {type: 'CALLS'}]->(f:Function {name: "validateUser"})
RETURN caller.name, caller.filePath ORDER BY caller.filePath

Risk Rules

Risk FactorMitigation
Many callers (>5)Use rename for automated updates
Cross-area refsUse detect_changes after to verify scope
String/dynamic refsquery to find them
External/public APIVersion and deprecate properly
Same name in another indexed repoBind repo; verify previewed paths before applying

Example: Rename validateUser to authenticateUser

0. list_repos {}
   → total: 2 (my-app, billing-api) — both define validateUser, so bind explicitly

1. rename({symbol_name: "validateUser", new_name: "authenticateUser", repo: "my-app", dry_run: true})
   → 12 edits: 10 graph (safe), 2 text_search (review)
   → Files: validator.ts, login.ts, middleware.ts, config.json...

2. Review text_search edits (config.json: dynamic reference!)

3. rename({symbol_name: "validateUser", new_name: "authenticateUser", repo: "my-app", dry_run: false})
   → Applied 12 edits across 8 files

4. detect_changes({scope: "all", repo: "my-app"})
   → Affected: LoginFlow, TokenRefresh
   → Risk: MEDIUM — run tests for these flows
   Repository: my-app (/abs/path/my-app)  Worktree: same  Index: current

With a single indexed repository, step 0 returns total: 1 and the repo argument drops out of every call above.