64 lines
2 KiB
Python
64 lines
2 KiB
Python
"""GlobTool — find files by glob pattern.
|
|
|
|
Uses pathlib.Path.glob and returns results sorted by modification time
|
|
(most recently modified first).
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
from typing import Any, ClassVar
|
|
|
|
from ..base import Tool, ToolParameter, ToolResult
|
|
|
|
|
|
class GlobTool(Tool):
|
|
"""Find files matching a glob pattern, sorted by modification time descending."""
|
|
|
|
name: ClassVar[str] = "glob"
|
|
description: ClassVar[str] = (
|
|
"Find files matching a glob pattern. "
|
|
"Returns results sorted by modification time (newest first)."
|
|
)
|
|
parameters: ClassVar[list[ToolParameter]] = [
|
|
ToolParameter(
|
|
name="pattern",
|
|
type="string",
|
|
description="Glob pattern to match (e.g., '**/*.py', 'src/**/*.ts')",
|
|
),
|
|
ToolParameter(
|
|
name="path",
|
|
type="string",
|
|
description="Base directory to search from (default: current working directory)",
|
|
required=False,
|
|
default=".",
|
|
),
|
|
]
|
|
|
|
async def execute(self, **kwargs: Any) -> ToolResult:
|
|
pattern: str = kwargs["pattern"]
|
|
base_path = Path(kwargs.get("path", "."))
|
|
|
|
if not base_path.exists():
|
|
return ToolResult.fail(f"Base path does not exist: {base_path}")
|
|
|
|
if not base_path.is_dir():
|
|
return ToolResult.fail(f"Base path is not a directory: {base_path}")
|
|
|
|
try:
|
|
matches = list(base_path.glob(pattern))
|
|
except ValueError as exc:
|
|
return ToolResult.fail(f"Invalid glob pattern: {exc}")
|
|
|
|
# Filter to files only (exclude directories)
|
|
files = [p for p in matches if p.is_file()]
|
|
|
|
# Sort by modification time, newest first
|
|
files.sort(key=lambda p: p.stat().st_mtime, reverse=True)
|
|
|
|
file_paths = [str(p) for p in files]
|
|
|
|
return ToolResult.success(
|
|
"\n".join(file_paths) if file_paths else "No files matched the pattern.",
|
|
total_matches=len(file_paths),
|
|
)
|