关于 gitnexus-refactoring
gitnexus-refactoring 是面向代码重构的 GitNexus 技能,涵盖语义重命名以及模块或服务调整。它强调确认仓库与工作树、检查影响并审阅预览,再验证修改结果。
主要功能
- 01绑定仓库与工作树
- 02梳理依赖方和代码引用
- 03预览语义重命名
- 04应用已审阅的重命名计划
- 05验证变更及受影响流程
适用场景
- 01跨受支持代码重命名符号
- 02将代码提取到模块
- 03拆分函数或服务
- 04重构前检查影响范围
MCP 相关
该技能指导 MCP 客户端使用 GitNexus 的 `list_repos`、`impact`、`context`、`rename` 和 `detect_changes` 等工具。`rename` 默认预览修改,并可在允许时应用已审阅的计划。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ abhigyanpatwari/ gitnexus --skill gitnexus-refactoring安装后在 Claude Code 中输入/gitnexus-refactoring确认已加载。
详细介绍
使用 GitNexus 重构
适用场景
- “安全地重命名此函数”
- “将此代码提取到模块中”
- “拆分此服务”
- “将此代码移到新文件中”
- 任何涉及重命名、提取、拆分或重组代码的任务
首先绑定仓库
重构会写入磁盘。rename 使用 dry_run: false 时,会编辑解析到的仓库中的文件,因此在此绑定身份是一道安全关卡,而非例行记录。
首次调用工具前,请先调用 list_repos {}。如果只有一个已建立索引的仓库,请按下方示例使用。若有多个仓库,请在每次调用时传入 repo:省略 repo 通常会报错,但如果 MCP 策略配置了默认值,则会静默解析到该默认值。如果无法确定目标仓库,请停止操作并询问。在同一绑定仓库中审查预览之前,绝不要使用 dry_run: false 运行 rename——返回的 file_path 值会显示即将写入的检出目录,因此请将其视为身份确认。
list_repos 会分页,因此请使用 offset: pagination.nextOffset 翻页,直到 hasMore 为 false,再判定仓库不存在。
如果你正在编辑 MCP 服务启动目录之外的关联工作树,detect_changes 需要传入 worktree;否则 git diff 会在错误的检出目录中运行并报告没有变化,这看起来就像重构已通过验证。
工作流
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
如果出现 “Index is stale”,请在终端运行
node .gitnexus/run.cjs analyze。热工具的staleness会标明响应所用索引(branch/lastCommit)及其新鲜度(status)。仅在状态为behind或diverged时重新分析;current表示身份,unknown表示无法测量。
检查清单
重命名符号
- [ ] list_repos {} — bind repo; explicit repo when >1 indexed, ask if ambiguous
- [ ] rename({symbol_name: "oldName", new_name: "newName", dry_run: true}) — preview semantic edits (omitting dry_run also previews)
- [ ] Confirm the previewed file paths are in the bound repository/worktree
- [ ] Review exact graph-backed semantic spans, coverage, and limitations
- [ ] If satisfied: rename({..., dry_run: false, plan_token: "<token from preview>"}) — apply exactly the reviewed edits
- [ ] detect_changes() — verify only expected files changed
- [ ] Run tests for affected processes
提取模块
- [ ] 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
拆分函数/服务
- [ ] 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
工具
rename — 语义重命名;先预览,再应用:
rename({symbol_name: "validateUser", new_name: "authenticateUser", repo: "my-app", dry_run: true})
→ 12 edits across 8 files
→ semantic_edits: 12, coverage: {name: "gitnexus-semantic", scope: "indexed-repository", limitations: [...]}
→ changes: [{file_path, edits: [{start, length, line, old_text, new_text, confidence: "semantic"}]}]
省略 dry_run 或设为 true 时会预览且不会写入;使用 dry_run: false 时必须提供成功预览返回的 plan_token。请保持仓库、所选符号和目标名称不变。令牌只能使用一次,并会在 15 分钟后或服务重启后过期;当保留的预览达到 16 个计划或 64 MiB 时,令牌也可能被淘汰。任何应用尝试都会消耗令牌;重试时请重新请求并审查预览。使用 GITNEXUS_MCP_READ_ONLY=1 启动的 MCP 服务仍会列出 rename,但仅可预览:它会拒绝任何非省略或非 true 的 dry_run,因此请通过允许写入的服务进行应用。请在该服务中重新请求并审查预览;令牌仅对签发它的进程有效。
重命名使用已建立索引的图谱和 GitNexus 自有的语义层。语言提供程序通过作用域和绑定解析当前源代码;不会加载编译器或语言服务。遇到不受支持的语法、存在歧义的绑定、过时的声明或不完整的匹配覆盖时,操作会安全失败。覆盖范围描述所选提供程序接受的已索引文件,包括受支持的嵌入式源代码,不包括未建立索引的文件和外部使用方。所有已注册的源语言提供程序都会提供重命名规则。声明和重写族需要完整的语义证据。如果提供程序无法解析动态或计算引用,或将其排除在所选族之外,这些引用就会阻止重命名。包括类重命名需要移动文件在内的提供程序特定限制,都会在结果中明确说明。没有正则表达式回退:旧版 graph_edits 和 text_search_edits 的值为零。注释、字符串以及名称相同但无关的符号都不会被替换。
预览会捕获精确的语义计划、源哈希和物理文件目标。
应用操作会验证该计划,并执行其中的编辑,不会重新规划。对已索引目标、源字节或路径所做的更改(包括新增的未跟踪源文件)都会导致计划在写入前被拒绝。未索引文件不在语义覆盖范围内;如需重构这些文件,请先进行分析。结果使用 result_version: 2;total_edits 统计的是出现次数,而非匹配行数。精确替换内容会显示在 new_text 中。请检查 planning_status、application_status 和 applied。已完成的应用操作具有 status: "success"、application_status: "applied" 和 applied: true。成功的预览不会写入文件。rename 不接受 branch:它会检查当前检出内容。
再次应用之前,请先从受阻或未完成的重命名操作中恢复。失败的结果会包含 code 和 error;除非最后一行适用,否则不会写入任何内容。
| 结果 | 下一步 |
|---|---|
stale_graph | 重新分析已绑定的仓库,然后使用 rename 再次预览(省略 dry_run 或设为 true)。 |
source_changed | 针对当前源码重新预览并检查。如果在应用过程中出现,请参阅 partial 行。 |
plan_required、invalid_plan、plan_mismatch | 应用需要成功预览所得的令牌,以及完全一致的仓库、符号和新名称。计划过期、已使用或已被移出缓存时,需要重新预览并检查。 |
source_set_changed | 源文件路径已发生变化,包括未跟踪的文件。重新分析并检查新的预览。 |
plan_too_large | 捕获的计划超过了 64 MiB 的保留预算。缩小已索引的仓库范围,然后重新预览。 |
unsupported_* | 停止自动重命名,并检查报告的限制。如有需要,请使用支持语言的手动重构。 |
目标不明确(status: "ambiguous" 且包含候选项) | 检查返回的候选项或 context,然后使用选定的 symbol_uid 进行预览。 |
ambiguous_reference、incomplete_semantics | 规划器无法证明某个引用、导入或声明已涵盖。停止自动重命名;手动处理指定位置,或选择其他符号。 |
name_collision | new_name 会与其他声明或绑定冲突,或改变其标识。选择其他名称并重新预览。 |
invalid_name | new_name 为空、与当前名称相同,或不符合目标语言的规则。选择一个有效且不同的标识符。 |
invalid_argument | 传入的 dry_run 不是布尔值。请省略它,或传入 true 或 false。 |
no_locations | 规划器未生成任何编辑。不要应用;使用 context 重新检查目标,并传入 symbol_uid。 |
overlapping_edits、invalid_edit | 计划中的范围相互冲突,或与源文本不匹配。计划会在任何写入发生前被拒绝;不要应用。请手动重构或报告此情况。 |
duplicate_file、missing_snapshot、outside_repository | 规划器的安全检查失败(两个路径解析到同一个实际文件、某个文件没有源快照,或路径指向仓库之外)。重新分析并预览;如果问题再次出现,请停止并报告。 |
source-unavailable(reason: "content-retention" 或 "checkout-missing") | 索引构建时未保留完整源码(GITNEXUS_CONTENT_RETENTION),或检出目录缺失。请使用完整保留设置重新分析,或针对检出目录运行。 |
rename_failed | 规划过程中发生意外错误,尚未进行任何写入(application_status: "not_started")。重新分析并再次预览;如果问题再次出现,请停止并报告 error 文本。 |
application_status: "partial" 或 "failed"(write_failed,或应用过程中出现 source_changed) | 写入不具备事务性。检查已落盘的 changes(已写入的文件及其计数)、failed_files(写入或验证失败的文件)和 unattempted_files(后续尚未触及的文件)。协调当前文件,重新建立索引并检查新的预览;切勿盲目重试应用调用。 |
应用后运行项目验证套件。
impact — 先映射所有依赖项:
impact({target: "validateUser", repo: "my-app", direction: "upstream"})
→ d=1: loginHandler, apiMiddleware, testUtils
→ Affected Processes: LoginFlow, TokenRefresh
detect_changes — 重构后验证更改:
detect_changes({scope: "all"})
→ Changed: 8 files, 12 symbols
→ Affected processes: LoginFlow, TokenRefresh
→ Risk: MEDIUM
partial: true(图查询失败)或 truncated: true(更改符号列表已截断)表示结果并不完整:列表很短或为空,并不能证明只有预期文件发生了变化。请重新运行,不要据此认定重构已验证。
错误工作树上的零结果不会带有这两个标志,因此无法与验证无误的结果区分;请确认显示差异的检出目录正是你编辑的目录。
cypher — 自定义引用查询:
MATCH (caller)-[:CodeRelation {type: 'CALLS'}]->(f:Function {name: "validateUser"})
RETURN caller.name, caller.filePath ORDER BY caller.filePath
风险规则
| 风险因素 | 缓解措施 |
|---|---|
| 调用方较多(>5) | 使用 rename 自动更新 |
| 跨区域引用 | 之后使用 detect_changes 验证范围 |
| 字符串/动态引用 | 使用 query 查找 |
| 外部/公共 API | 正确进行版本管理和弃用 |
| 其他已索引仓库中存在同名项 | 绑定 repo;应用前核对预览的路径 |
示例:将 validateUser 重命名为 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 semantic occurrences in the indexed repository's supported provider scope
→ Files: validator.ts, login.ts, middleware.ts...
2. Review semantic spans and provider coverage; inspect dynamic references separately
3. rename({symbol_name: "validateUser", new_name: "authenticateUser", repo: "my-app", dry_run: false, plan_token: "<token from step 1>"})
→ 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
如果只有一个已索引的仓库,步骤 0 会返回 total: 1,上面每次调用中的 repo
参数都会省略。