From xcindex
Produce a complete written refactor plan for Swift or Objective-C code — rename, signature change, type extraction, protocol split, API migration — listing every site that will change (grouped by file with line numbers), the risks (overrides, conformances, @objc bridging, cross-module public API, test coverage), and the recommended execution path. Pure planning — makes zero edits. Use whenever the user wants to scope, preview, or estimate a Swift change before committing to it.
How this skill is triggered — by the user, by Claude, or both
Slash command
/xcindex:swift-refactor-planWhen to use
Trigger on planning-flavored phrasing like "plan a rename of X", "what would changing X involve", "before I rename, show me what changes", "I'm thinking about extracting Y", "preview the rename of Z", "scope this refactor", "what is the impact of changing AuthService's signature", "draft a migration plan from old API to new", "is this rename safe", "how big a change is this". Also reach for this skill whenever the user is in plan-mode-style discussion about Swift code, even without the word "plan" — any request to understand a change before making it qualifies. Use BEFORE swift-rename-symbol when the user wants to inspect the surface first. Skip and go straight to swift-rename-symbol / swift-find-references when the user has clearly committed ("just do it", "go ahead and rename", "apply it now").
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Builds a written plan for a Swift refactor. It does **not** edit code. The plan
Builds a written plan for a Swift refactor. It does not edit code. The plan is what you hand to the user (or to swift-rename-symbol) so the actual edits can happen with full context.
A good plan answers four questions:
@objc bridging, public API
crossing module boundaries, missing test coverage.swift-rename-symbol, manual edits in N files, or "this needs more design
work first."The xcindex MCP tools provide the raw data; this skill orchestrates the queries and turns the result into a plan.
The user's phrasing tells you whether the unit is a symbol or a file.
fetchUser to loadUser" → symbol.NetworkClient.swift into two files" → file.OldAuthAPI to NewAuthAPI" → multiple symbols (treat each
separately, then aggregate).If the user named only a file but the change is really about a symbol inside it
(e.g. "what if I change the signature of the function in Auth.swift"),
disambiguate before querying.
Run only the queries that match the target shape. Skip anything irrelevant.
Symbol target:
find_symbol(symbolName: <name>) → resolve to a USR. If multiple results,
pick the one matching the user's stated module/kind, or ask.find_definition(usr: <usr from step 1>) → confirm the definition site.find_references(symbolName: <name>, maxResults: 200) → every reference.find_overrides(usr: <usr from step 1>) —
subclass overrides break silently if missed.find_conformances(usr: <usr from step 1>) — every conformer must update.File target:
blast_radius(filePath: <abs path>) → directDependents, affectedFiles,
coveringTests.find_references for the specific symbols
inside the file the user is changing.Walk the results and flag each of these that applies:
| Risk | Signal |
|---|---|
| Overrides | find_overrides returns ≥1 site — subclasses must change in lockstep. |
| Protocol conformances | find_conformances returns ≥1 site — every conformer must update. |
@objc bridging | find_references returns sites with .dynamic role — Objective-C call sites outside the index may exist. |
| Cross-module public API | Reference sites span multiple modules — downstream packages may break. |
| No covering tests | blast_radius.coveringTests is empty for the affected files — regression risk; recommend adding one before the change. |
| Stale index | MCP returned a freshness warning — note that the plan may be incomplete until the user rebuilds. |
A risk-free plan is fine — write "No notable risks" rather than inventing filler.
Use this exact structure so plans are skimmable and the user can act on them directly:
## Refactor plan: <one-line description>
**Target:** <symbol or file, with USR if applicable>
**Type:** <rename | signature change | extraction | migration | other>
**Total impact:** <N files, M reference sites>
### Sites by file
- `path/to/A.swift` (<count>)
- L<line> — <role: call | override | conformance | definition | test>
- L<line> — ...
- `path/to/B.swift` (<count>)
- ...
### Covering tests
- `path/to/ATests.swift`
- ...
(or "None — recommend adding test coverage before proceeding")
### Risks
- ⚠ <risk> — <one-sentence explanation>
- ✓ <thing-that-could-have-been-a-risk-but-isn't>
### Recommended execution
<one of:>
- Use `swift-rename-symbol` — dispatches the rename via the
swift-refactor-specialist subagent. Estimated subagent context: ~Xk tokens
(roughly: site count × 80 tokens/site + 200 tokens/file read).
- Manual edits in <list of files> — recommended when sites need
case-by-case judgment (e.g. some calls need migration shims).
- Pause and decide on <X> first — recommended when the plan surfaces a design
question the rename can't resolve (e.g. an `@objc` requirement, a behavior
change disguised as a rename).
End your message by telling the user what's available next:
<file> so you can review the first edit?" (if manual)Don't start editing on your own — this skill's job ends with the plan.
User: "I'm thinking about renaming fetchUser to loadUser. What would
that touch?"
You:
find_symbol(symbolName: "fetchUser") → one USR, in MyApp.UserService.find_references(symbolName: "fetchUser", maxResults: 200) → 11 sites across 6 files.find_overrides(usr: "s:9MyApp11UserServiceC9fetchUserSiyF") → 0 (it's a free function on the class).## Refactor plan: rename `UserService.fetchUser` → `loadUser`
**Target:** `s:9MyApp...fetchUserSiF` (UserService.fetchUser)
**Type:** rename
**Total impact:** 6 files, 11 sites
### Sites by file
- `Sources/UserService.swift` (2)
- L42 — definition
- L67 — internal call
- `Sources/AuthFlow.swift` (3)
- L18, L24, L91 — calls
- `Sources/ProfileViewModel.swift` (2)
- L33, L120 — calls
- `Tests/UserServiceTests.swift` (3)
- L12, L45, L88 — calls
- `Tests/AuthFlowTests.swift` (1)
- L23 — call
### Covering tests
- `Tests/UserServiceTests.swift`
- `Tests/AuthFlowTests.swift`
### Risks
- ✓ No subclass overrides.
- ✓ No protocol conformance — it's a concrete method.
- ✓ Not `@objc` — no Objective-C bridging surface.
- ✓ Tests cover both the direct method and one downstream caller.
### Recommended execution
Use `swift-rename-symbol` — straightforward rename, all sites are direct calls,
test coverage is solid. Estimated subagent context: ~2k tokens.
"Want me to dispatch this to swift-rename-symbol?"
swift-rename-symbol directly.TODO?") — that's
Grep, not the index.Searches MemPalace before answering questions about past work, people, projects, or prior decisions. Returns verbatim stored content instead of guessing from model memory.
Guides Payload CMS config (payload.config.ts), collections, fields, hooks, access control, APIs. Debugs validation errors, security, relationships, queries, transactions, hook behavior.
Implements vector databases with Pinecone, Weaviate, Qdrant, Milvus, pgvector for semantic search, RAG, recommendations, and similarity systems. Optimizes embeddings, indexing, and hybrid search.
npx claudepluginhub drewalth/claude-xcindex --plugin xcindex