Summary
refactor_tool(mode="dead_code") returns items with only 5 fields (name, qualified_name, kind, file, line) but the tool's docstring / schema hint advertises additional fields including relative_path, file_path, and language. The documented fields are missing entirely on every entry.
Version
code-review-graph==2.3.2 (also reproducible on main as of 4b6293f)
Reproduction
refactor_tool(mode="dead_code", kind="Function", repo_root="/path/to/any/repo")
Each entry in dead_code[]:
{
"name": "...",
"qualified_name": "...",
"kind": "Function",
"file": "/abs/path/to/file.py",
"line": 123
}
relative_path, file_path, and language are missing on every entry (not even null).
Root cause
In code_review_graph/refactor.py, find_dead_code() builds the per-entry dict at lines ~561-567:
dead.append({
"name": _sanitize_name(node.name),
"qualified_name": _sanitize_name(node.qualified_name),
"kind": node.kind,
"file": node.file_path,
"line": node.line_start,
})
The wrapper in tools/refactor_tools.py::dead_code branch returns dead as-is. Nothing enriches it with relative_path or language, even though both are derivable: the calling tool has root from _get_store(repo_root), and node.language is already on the GraphNode model.
Suggested fix
Option A (preferred): enrich the entries in tools/refactor_tools.py after dead = find_dead_code(...):
from pathlib import Path
EXT_LANG = {".py":"python", ".ts":"typescript", ".tsx":"typescript",
".js":"javascript", ".jsx":"javascript", ".go":"go", ".rs":"rust",
".java":"java", ".rb":"ruby", ".sh":"bash", ".ex":"elixir",
".exs":"elixir", ".m":"objective-c", ".mm":"objective-c",
".c":"c", ".cpp":"cpp", ".cc":"cpp", ".h":"c", ".hpp":"cpp",
".cs":"csharp", ".php":"php", ".swift":"swift",
".kt":"kotlin", ".scala":"scala"}
for entry in dead:
abs_path = entry["file"]
entry["file_path"] = abs_path
try:
entry["relative_path"] = str(Path(abs_path).resolve().relative_to(root))
except ValueError:
entry["relative_path"] = abs_path
entry["language"] = EXT_LANG.get(Path(abs_path).suffix.lower(), "unknown")
Even better: pull language directly off the GraphNode in find_dead_code (it's already on the model).
Option B: update the schema/hint string to match the 5-field reality. Less useful but trivial.
Companion request (optional)
find_dead_code returned 817 entries on a 4,525-node graph in our repo. A large fraction were template files (.claude/skills/*/modify/src/...) and one-shot training/backtest snapshots (data/files/*.py) which are intentionally never executed at runtime.
find_large_functions_tool already supports file_path_pattern. Adding a symmetric exclude_pattern to refactor_tool(mode="dead_code") would let consumers filter known-snapshot directories without post-processing 800+ false positives.
Acceptance criteria
dead_code[] items include relative_path, file_path, and language fields (Option A), or
- Schema/docstring updated to advertise only the 5 fields actually returned (Option B)
- Optional:
exclude_pattern parameter symmetric to file_pattern
Summary
refactor_tool(mode="dead_code")returns items with only 5 fields (name,qualified_name,kind,file,line) but the tool's docstring / schema hint advertises additional fields includingrelative_path,file_path, andlanguage. The documented fields are missing entirely on every entry.Version
code-review-graph==2.3.2(also reproducible on main as of4b6293f)Reproduction
Each entry in
dead_code[]:{ "name": "...", "qualified_name": "...", "kind": "Function", "file": "/abs/path/to/file.py", "line": 123 }relative_path,file_path, andlanguageare missing on every entry (not even null).Root cause
In
code_review_graph/refactor.py,find_dead_code()builds the per-entry dict at lines ~561-567:The wrapper in
tools/refactor_tools.py::dead_codebranch returnsdeadas-is. Nothing enriches it withrelative_pathorlanguage, even though both are derivable: the calling tool hasrootfrom_get_store(repo_root), andnode.languageis already on the GraphNode model.Suggested fix
Option A (preferred): enrich the entries in
tools/refactor_tools.pyafterdead = find_dead_code(...):Even better: pull
languagedirectly off the GraphNode infind_dead_code(it's already on the model).Option B: update the schema/hint string to match the 5-field reality. Less useful but trivial.
Companion request (optional)
find_dead_codereturned 817 entries on a 4,525-node graph in our repo. A large fraction were template files (.claude/skills/*/modify/src/...) and one-shot training/backtest snapshots (data/files/*.py) which are intentionally never executed at runtime.find_large_functions_toolalready supportsfile_path_pattern. Adding a symmetricexclude_patterntorefactor_tool(mode="dead_code")would let consumers filter known-snapshot directories without post-processing 800+ false positives.Acceptance criteria
dead_code[]items includerelative_path,file_path, andlanguagefields (Option A), orexclude_patternparameter symmetric tofile_pattern