Code impact radius
Know what breaks before you rename it. A precise TypeScript symbol-reference tool — definition, calls, imports, re-exports, transitive callers — as text, JSON, or a Mermaid diagram. Built on ts-morph. AI-agent friendly.
npx -y skills add Faris-Alanazi/code-impact-radiusAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Use BEFORE any rename, refactor, type-shape change, deletion, or "what depends on X" question in a TypeScript / TSX codebase. Returns every place a symbol is defined, read, written, called, instantiated, imported, re-exported, plus its transitive callers up to a configurable depth. Far cheaper than grep+read because it queries a typed reference index built from the TypeScript Compiler — no false positives from string matches in comments or unrelated identifiers with the same name. Triggers on phrases like "what calls X", "where is X used", "blast radius of X", "impact of renaming X", "find all references to X", "who depends on X", "what breaks if I change X".
SKILL.md
5.6 KB, as published. Nobody here has run it
Code Impact Radius
The structured replacement for grep -r <name> followed by reading every match.
When to invoke
Whenever you (or the user) is about to:
- Rename a function, variable, class, type, interface, or enum
- Change the shape of a type or function signature
- Move or delete a file / module / barrel export
- Audit who depends on a particular symbol (security review, deprecation, refactor planning)
- Decide whether a change is "safe to do alone" or "needs coordinated rollout"
- Answer "what calls X", "where is X used", "who imports X", "blast radius of X"
This is the right tool whenever the question is "what connects to this symbol?"
How to invoke
node ~/.claude/skills/code-impact-radius/src/cli.js <symbolName> --project <path> --json
Or — if you want pretty terminal output instead of JSON:
node ~/.claude/skills/code-impact-radius/src/cli.js <symbolName> --project <path> --pretty
JSON is the default when stdout is not a TTY (so AI agents always get JSON).
Options
| Flag | What it does |
|---|---|
--project <path> | Project root containing tsconfig.json (default: cwd) |
--depth <n> | Transitive caller depth (default 2, max 10) |
--kind <kind> | Filter declaration kind: variable function class method interface type enum |
--at <file>:<line> | Disambiguate when the name has multiple declarations |
--include-tests | Include *.test.ts / *.spec.ts in references (default: skip) |
--max-sites <n> | Truncate references.sites to first N entries |
--json / --pretty | Force output mode |
--mermaid | Emit a Mermaid flowchart diagram (paste into a Markdown ```mermaid block — GitHub, GitLab, VS Code, Obsidian, Notion render natively). |
Exit codes
| Code | Meaning |
|---|---|
| 0 | Success — exactly one match, OR ambiguous list with N candidates |
| 1 | CLI usage error / runtime error |
| 2 | Symbol name not found |
Reading the JSON output
{
"query": // what was asked
"matched": // how many declarations matched the name
"candidates": // disambiguation list (only when matched > 1 or 0)
"symbol": {
"name": // canonical name
"kind": // function | class | variable | ...
"definition": {
"file": "...", "line": 42, "column": 17,
"snippet": "export function formatPrice..."
}
},
"references": {
"totalCount": 14,
"byKind": {
"definition": 1,
"call": 8,
"import": 3,
"reExport": 1,
"read": 1,
"instantiation": 0,
"jsx": 0,
"type": 0,
"write": 0
},
"sites": [
{ "file": "...", "line": 18, "kind": "call", "snippet": "formatPrice(price, locale)", "parentKind": "CallExpression" }
],
"truncated": 0
},
"imports": {
"exportedFrom": "src/lib/utils.ts",
"importedBy": // every file that imports this symbol
"reExportedFrom": // every barrel that re-exports it
},
"transitiveCallers": {
"depth": 2,
"callers": [
{ "depth": 1, "file": "...", "line": 18, "function": "PriceTag", "functionKind": "FunctionDeclaration" },
{ "depth": 2, "file": "...", "line": 87, "function": "CheckoutPage", "functionKind": "FunctionDeclaration" }
]
},
"warnings": []
}
Disambiguation flow
If matched > 1, the tool returns candidates and asks for a --at <file>:<line> to pick one:
$ code-impact-radius id --project ./app --json
# matched: 3, symbol: null, candidates: [{file, line, kind} × 3]
$ code-impact-radius id --project ./app --at src/ambig.ts:11 --json
# matched: 1, symbol: { ... }
Decision-flow guidance for blast-radius checks
Use this output to drive a structured impact table:
- Definition — read the file at
symbol.definition.file:lineto see the contract you're about to change. - References by kind — every
call,instantiation,jsx,read,writesite is a potential breakage. - Imports — every
imports.importedByentry needs updating if you rename the symbol. - Re-exports — barrels in
imports.reExportedFromneed updating too. - Transitive callers — depth 2-3 catches most "indirect callers" that grep would miss.
Then build the impact table (file:line | usage | status: todo/done/verified-unaffected) and tick each row off as you go.
What this tool does NOT cover
- String literals — i18n keys (
t('home.title')), SQL fragments, env-var names, URL paths. Use grep for those. - Dynamic imports —
import('./mod')calls aren't traced. - Cross-language — TypeScript / TSX only. Python / Rust / Go / SQL stay grep territory.
For string-literal scans, run grep alongside this tool. The two together cover the full surface.
Performance
Cold-load on a ~200 TS/TSX file project: ~1.5s per query. ~700-file projects: ~5-8s. The TypeScript compiler initializes once per CLI invocation, so repeated queries in one session each pay that cost.