# file_scanner.py
from __future__ import annotations
from pathlib import Path
from typing import List
EXCLUDED_DIRS = {
".venv",
"venv",
".mcp",
".git",
"__pycache__",
"node_modules",
"site-packages",
"dist",
"build",
".pytest_cache",
}
def discover_python_sources(root: Path) -> List[Path]:
"""
Returns a list of Python source files under the project root, excluding
virtual environments, cache directories, and tool folders.
"""
root = root.resolve()
result: List[Path] = []
for file in root.rglob("*.py"):
# Skip file paths containing any excluded directory
if any(part in EXCLUDED_DIRS for part in file.parts):
continue
# Only include real project files
if file.is_file():
result.append(file)
return result
def relative_to_root(paths: List[Path], root: Path) -> List[str]:
root = root.resolve()
return [str(p.resolve().relative_to(root)) for p in paths]