From d5914f624867c989cd77e40ff9ab16119758ee0d Mon Sep 17 00:00:00 2001 From: sanguine59 Date: Sun, 16 Aug 2026 14:05:49 +0700 Subject: [PATCH] docs(claude-skills): update gitnexus-refactoring --- .claude/skills/gitnexus-refactoring/SKILL.md | 78 +++++++++++++++----- 1 file changed, 61 insertions(+), 17 deletions(-) diff --git a/.claude/skills/gitnexus-refactoring/SKILL.md b/.claude/skills/gitnexus-refactoring/SKILL.md index 4f10bbc6a..7cdceb4b7 100644 --- a/.claude/skills/gitnexus-refactoring/SKILL.md +++ b/.claude/skills/gitnexus-refactoring/SKILL.md @@ -13,67 +13,95 @@ description: "Use when the user wants to rename, extract, split, move, or restru - "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 {}`. With one indexed repository, use the +examples below as written. With more than one, pass `repo` explicitly on every +call — an omitted `repo` errors, or silently resolves to a configured default — +and stop and ask if the intended repository is ambiguous. Pass `worktree` to +`detect_changes` when you are editing a linked worktree the server was not +launched from. See `references/repository-identity.md`. + +Never run `rename` with `dry_run: false` until the preview in the same bound +repository has been reviewed. + ## Workflow ``` -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 +0. list_repos {} → Bind repo (and worktree) +1. impact({target: "X", direction: "upstream"[, repo: ""]}) → Map all dependents +2. query({search_query: "X"[, repo: ""]}) → Find execution flows involving X +3. context({name: "X"[, repo: ""]}) → 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. +> If "Index is stale" → run `node .gitnexus/run.cjs analyze` in the bound checkout. +> A stale index under a rename means edits planned against code that has moved. ## Checklists ### Rename Symbol ``` +- [ ] list_repos {} — bind repo; explicit repo when total > 1, 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 +- [ ] detect_changes({scope: "all"}) — verify only expected files changed - [ ] Run tests for affected processes ``` ### Extract Module ``` +- [ ] list_repos {} — bind repo; explicit repo when total > 1, 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 +- [ ] detect_changes({scope: "all"}) — verify affected scope - [ ] Run tests for affected processes ``` ### Split Function/Service ``` +- [ ] list_repos {} — bind repo; explicit repo when total > 1, 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 +- [ ] detect_changes({scope: "all"}) — verify affected scope - [ ] Run tests for affected processes ``` +Each `detect_changes` above takes `worktree` when the checkout you edited is +not the one the MCP server was launched from. Without it the diff runs in the +wrong tree and reports nothing changed, which reads as a verified refactor. + ## Tools **rename** — automated multi-file rename: ``` -rename({symbol_name: "validateUser", new_name: "authenticateUser", dry_run: true}) +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}]}] ``` +Read the returned `file_path` values as a confirmation of identity: they show +which checkout is about to be written. If they are not the paths you intend, +stop — do not re-run with `dry_run: false`. + **impact** — map all dependents first: ``` -impact({target: "validateUser", direction: "upstream"}) +impact({target: "validateUser", repo: "my-app", direction: "upstream"}) → d=1: loginHandler, apiMiddleware, testUtils → Affected Processes: LoginFlow, TokenRefresh ``` @@ -81,7 +109,7 @@ impact({target: "validateUser", direction: "upstream"}) **detect_changes** — verify your changes after refactoring: ``` -detect_changes({scope: "all"}) +detect_changes({scope: "all", repo: "my-app", worktree: "/abs/path/to/checkout"}) → Changed: 8 files, 12 symbols → Affected processes: LoginFlow, TokenRefresh → Risk: MEDIUM @@ -89,14 +117,19 @@ detect_changes({scope: "all"}) `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. +list is not proof that only the expected files changed. A wrong-worktree zero +carries neither flag and is indistinguishable from a clean verification, so +confirm the diffed checkout is the one you edited. Re-run it rather than treat +the refactor as verified. -**cypher** — custom reference queries: +**cypher** — custom reference queries. Pass `repo` alongside the statement; the +Cypher text names no repository: -```cypher +``` +cypher({repo: "my-app", statement: ` MATCH (caller)-[:CodeRelation {type: 'CALLS'}]->(f:Function {name: "validateUser"}) RETURN caller.name, caller.filePath ORDER BY caller.filePath +`}) ``` ## Risk Rules @@ -107,20 +140,31 @@ RETURN caller.name, caller.filePath ORDER BY caller.filePath | Cross-area refs | Use detect_changes after to verify scope | | String/dynamic refs | query to find them | | External/public API | Version and deprecate properly | +| Same symbol name in another indexed repo | Bind `repo` explicitly; verify previewed paths before applying | ## Example: Rename `validateUser` to `authenticateUser` ``` -1. rename({symbol_name: "validateUser", new_name: "authenticateUser", dry_run: true}) +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... + → Paths are under /abs/path/my-app — the intended checkout ✓ 2. Review text_search edits (config.json: dynamic reference!) -3. rename({symbol_name: "validateUser", new_name: "authenticateUser", dry_run: false}) +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"}) +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.