Skip to content

refactor_tool(mode='dead_code'): response items missing documented relative_path / file_path / language fields #447

@johndowbs

Description

@johndowbs

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions