Private
Public Access
basic mcp org
This commit is contained in:
+62
-56
@@ -576,6 +576,28 @@ def edit_file(path: str, old_string: str, new_string: str, replace_all: bool = F
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
return f"ERROR editing '{path}': {e}"
|
return f"ERROR editing '{path}': {e}"
|
||||||
|
|
||||||
|
def get_git_diff(path: str, base_rev: str = "HEAD", head_rev: str = "") -> str:
|
||||||
|
"""
|
||||||
|
Returns the git diff for a file or directory.
|
||||||
|
base_rev: The base revision (default: HEAD)
|
||||||
|
head_rev: The head revision (optional)
|
||||||
|
"""
|
||||||
|
p, err = _resolve_and_check(path)
|
||||||
|
if err:
|
||||||
|
return err
|
||||||
|
assert p is not None
|
||||||
|
cmd = ["git", "diff", base_rev]
|
||||||
|
if head_rev:
|
||||||
|
cmd.append(head_rev)
|
||||||
|
cmd.extend(["--", str(p)])
|
||||||
|
try:
|
||||||
|
result = subprocess.run(cmd, capture_output=True, text=True, check=True, encoding="utf-8")
|
||||||
|
return result.stdout if result.stdout else "(no changes)"
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
return f"ERROR running git diff: {e.stderr}"
|
||||||
|
except Exception as e:
|
||||||
|
return f"ERROR: {e}"
|
||||||
|
|
||||||
def _get_symbol_node(tree: ast.AST, name: str) -> Optional[ast.AST]:
|
def _get_symbol_node(tree: ast.AST, name: str) -> Optional[ast.AST]:
|
||||||
"""Helper to find an AST node by name (Class, Function, or Variable). Supports dot notation."""
|
"""Helper to find an AST node by name (Class, Function, or Variable). Supports dot notation."""
|
||||||
parts = name.split(".")
|
parts = name.split(".")
|
||||||
@@ -602,6 +624,8 @@ def _get_symbol_node(tree: ast.AST, name: str) -> Optional[ast.AST]:
|
|||||||
current = found
|
current = found
|
||||||
return current
|
return current
|
||||||
|
|
||||||
|
#region: Python AST
|
||||||
|
|
||||||
def py_get_symbol_info(path: str, name: str) -> tuple[str, int] | str:
|
def py_get_symbol_info(path: str, name: str) -> tuple[str, int] | str:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@@ -806,30 +830,6 @@ def py_set_var_declaration(path: str, name: str, new_declaration: str) -> str:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
return f"ERROR updating variable '{name}' in '{path}': {e}"
|
return f"ERROR updating variable '{name}' in '{path}': {e}"
|
||||||
|
|
||||||
def get_git_diff(path: str, base_rev: str = "HEAD", head_rev: str = "") -> str:
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
Returns the git diff for a file or directory.
|
|
||||||
base_rev: The base revision (default: HEAD)
|
|
||||||
head_rev: The head revision (optional)
|
|
||||||
"""
|
|
||||||
p, err = _resolve_and_check(path)
|
|
||||||
if err:
|
|
||||||
return err
|
|
||||||
assert p is not None
|
|
||||||
cmd = ["git", "diff", base_rev]
|
|
||||||
if head_rev:
|
|
||||||
cmd.append(head_rev)
|
|
||||||
cmd.extend(["--", str(p)])
|
|
||||||
try:
|
|
||||||
result = subprocess.run(cmd, capture_output=True, text=True, check=True, encoding="utf-8")
|
|
||||||
return result.stdout if result.stdout else "(no changes)"
|
|
||||||
except subprocess.CalledProcessError as e:
|
|
||||||
return f"ERROR running git diff: {e.stderr}"
|
|
||||||
except Exception as e:
|
|
||||||
return f"ERROR: {e}"
|
|
||||||
|
|
||||||
def py_find_usages(path: str, name: str) -> str:
|
def py_find_usages(path: str, name: str) -> str:
|
||||||
"""Finds exact string matches of a symbol in a given file or directory."""
|
"""Finds exact string matches of a symbol in a given file or directory."""
|
||||||
p, err = _resolve_and_check(path)
|
p, err = _resolve_and_check(path)
|
||||||
@@ -964,38 +964,6 @@ def py_get_docstring(path: str, name: str) -> str:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
return f"ERROR getting docstring for '{name}': {e}"
|
return f"ERROR getting docstring for '{name}': {e}"
|
||||||
|
|
||||||
def get_tree(path: str, max_depth: int = 2) -> str:
|
|
||||||
"""Returns a directory structure up to a max depth."""
|
|
||||||
p, err = _resolve_and_check(path)
|
|
||||||
if err: return err
|
|
||||||
assert p is not None
|
|
||||||
if not p.is_dir(): return f"ERROR: not a directory: {path}"
|
|
||||||
try:
|
|
||||||
m_depth = max_depth
|
|
||||||
|
|
||||||
def _build_tree(dir_path: Path, current_depth: int, prefix: str = "") -> list[str]:
|
|
||||||
if current_depth > m_depth: return []
|
|
||||||
lines = []
|
|
||||||
try:
|
|
||||||
entries = sorted(dir_path.iterdir(), key=lambda e: (e.is_file(), e.name.lower()))
|
|
||||||
except PermissionError:
|
|
||||||
return []
|
|
||||||
# Filter
|
|
||||||
entries = [e for e in entries if not e.name.startswith('.') and e.name not in ('__pycache__', 'venv', 'env') and e.name != "history.toml" and not e.name.endswith("_history.toml")]
|
|
||||||
for i, entry in enumerate(entries):
|
|
||||||
is_last = (i == len(entries) - 1)
|
|
||||||
connector = "└── " if is_last else "├── "
|
|
||||||
lines.append(f"{prefix}{connector}{entry.name}")
|
|
||||||
if entry.is_dir():
|
|
||||||
extension = " " if is_last else "│ "
|
|
||||||
lines.extend(_build_tree(entry, current_depth + 1, prefix + extension))
|
|
||||||
return lines
|
|
||||||
tree_lines = [f"{p.name}/"] + _build_tree(p, 1)
|
|
||||||
return "\n".join(tree_lines)
|
|
||||||
except Exception as e:
|
|
||||||
return f"ERROR generating tree for '{path}': {e}"
|
|
||||||
# ------------------------------------------------------------------ web tools
|
|
||||||
|
|
||||||
def derive_code_path(target: str, max_depth: int = 5) -> str:
|
def derive_code_path(target: str, max_depth: int = 5) -> str:
|
||||||
"""Recursively traces the execution path of a specific function or method."""
|
"""Recursively traces the execution path of a specific function or method."""
|
||||||
from src.file_cache import ASTParser
|
from src.file_cache import ASTParser
|
||||||
@@ -1056,6 +1024,42 @@ def derive_code_path(target: str, max_depth: int = 5) -> str:
|
|||||||
trace(symbol_name, found_path, found_code, 0, "")
|
trace(symbol_name, found_path, found_code, 0, "")
|
||||||
return "\n".join(output)
|
return "\n".join(output)
|
||||||
|
|
||||||
|
#endregion Python AST
|
||||||
|
|
||||||
|
def get_tree(path: str, max_depth: int = 2) -> str:
|
||||||
|
"""Returns a directory structure up to a max depth."""
|
||||||
|
p, err = _resolve_and_check(path)
|
||||||
|
if err: return err
|
||||||
|
assert p is not None
|
||||||
|
if not p.is_dir(): return f"ERROR: not a directory: {path}"
|
||||||
|
try:
|
||||||
|
m_depth = max_depth
|
||||||
|
|
||||||
|
def _build_tree(dir_path: Path, current_depth: int, prefix: str = "") -> list[str]:
|
||||||
|
if current_depth > m_depth: return []
|
||||||
|
lines = []
|
||||||
|
try:
|
||||||
|
entries = sorted(dir_path.iterdir(), key=lambda e: (e.is_file(), e.name.lower()))
|
||||||
|
except PermissionError:
|
||||||
|
return []
|
||||||
|
# Filter
|
||||||
|
entries = [e for e in entries if not e.name.startswith('.') and e.name not in ('__pycache__', 'venv', 'env') and e.name != "history.toml" and not e.name.endswith("_history.toml")]
|
||||||
|
for i, entry in enumerate(entries):
|
||||||
|
is_last = (i == len(entries) - 1)
|
||||||
|
connector = "└── " if is_last else "├── "
|
||||||
|
lines.append(f"{prefix}{connector}{entry.name}")
|
||||||
|
if entry.is_dir():
|
||||||
|
extension = " " if is_last else "│ "
|
||||||
|
lines.extend(_build_tree(entry, current_depth + 1, prefix + extension))
|
||||||
|
return lines
|
||||||
|
tree_lines = [f"{p.name}/"] + _build_tree(p, 1)
|
||||||
|
return "\n".join(tree_lines)
|
||||||
|
except Exception as e:
|
||||||
|
return f"ERROR generating tree for '{path}': {e}"
|
||||||
|
# ------------------------------------------------------------------ web tools
|
||||||
|
|
||||||
|
#region: Web
|
||||||
|
|
||||||
class _DDGParser(HTMLParser):
|
class _DDGParser(HTMLParser):
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
@@ -1161,6 +1165,8 @@ def fetch_url(url: str) -> str:
|
|||||||
return full_text
|
return full_text
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return f"ERROR fetching URL '{url}': {e}"
|
return f"ERROR fetching URL '{url}': {e}"
|
||||||
|
|
||||||
|
#endregion: Web
|
||||||
|
|
||||||
def get_ui_performance() -> str:
|
def get_ui_performance() -> str:
|
||||||
"""
|
"""
|
||||||
|
|||||||
Reference in New Issue
Block a user