HumboldtJoker commited on
Commit
53b6c1d
·
verified ·
1 Parent(s): eb6356e

Clean up nested duplicate: v2/v2/tools/file_tools.py

Browse files
Files changed (1) hide show
  1. v2/v2/tools/file_tools.py +0 -113
v2/v2/tools/file_tools.py DELETED
@@ -1,113 +0,0 @@
1
- """Git-aware file access for the campus repo.
2
-
3
- Reads are jailed to the configured repo root. Writes additionally
4
- require the target to be clean in git (no clobbering uncommitted work)
5
- and are disabled entirely unless the operator turns them on in config —
6
- Rivet is a colleague that suggests; writing into the repo is a
7
- consensus-gated action.
8
- """
9
-
10
- import re
11
- from dataclasses import dataclass, field
12
- from pathlib import Path
13
-
14
- from tools.guard import ToolResult, check_path, run_checked
15
-
16
- MAX_READ_BYTES = 200_000
17
-
18
-
19
- @dataclass
20
- class FileReadResult:
21
- ok: bool
22
- path: str = ""
23
- content: str = ""
24
- truncated: bool = False
25
- git_status: str = "" # '' = clean/untracked-unknown, else porcelain code
26
- error: str = ""
27
-
28
-
29
- @dataclass
30
- class RepoFiles:
31
- repo_root: str
32
- write_enabled: bool = False
33
- files_read: list = field(default_factory=list)
34
-
35
- def _jail(self, rel_path: str) -> tuple:
36
- target = Path(self.repo_root) / rel_path
37
- reason = check_path(target, [self.repo_root])
38
- return target, reason
39
-
40
- def read(self, rel_path: str) -> FileReadResult:
41
- target, reason = self._jail(rel_path)
42
- if reason:
43
- return FileReadResult(ok=False, path=rel_path, error=reason)
44
- if not target.exists():
45
- return FileReadResult(ok=False, path=rel_path,
46
- error=f"not found: {rel_path}")
47
- if not target.is_file():
48
- return FileReadResult(ok=False, path=rel_path,
49
- error=f"not a file: {rel_path}")
50
- raw = target.read_bytes()
51
- truncated = len(raw) > MAX_READ_BYTES
52
- content = raw[:MAX_READ_BYTES].decode("utf-8", errors="replace")
53
- self.files_read.append(rel_path)
54
- return FileReadResult(
55
- ok=True, path=rel_path, content=content, truncated=truncated,
56
- git_status=self._git_status(rel_path),
57
- )
58
-
59
- def write(self, rel_path: str, content: str) -> ToolResult:
60
- if not self.write_enabled:
61
- return ToolResult(
62
- ok=False,
63
- blocked_reason=("repo writes are disabled by config "
64
- "(tools.repo_write_enabled) — Rivet suggests, "
65
- "humans apply"),
66
- )
67
- target, reason = self._jail(rel_path)
68
- if reason:
69
- return ToolResult(ok=False, blocked_reason=reason)
70
- status = self._git_status(rel_path)
71
- if status and status != "??":
72
- return ToolResult(
73
- ok=False,
74
- blocked_reason=(f"{rel_path} has uncommitted changes "
75
- f"(git status '{status}') — refusing to clobber"),
76
- )
77
- target.parent.mkdir(parents=True, exist_ok=True)
78
- target.write_text(content)
79
- return ToolResult(ok=True, stdout=f"wrote {rel_path}")
80
-
81
- def search(self, pattern: str, glob: str = "", max_results: int = 50) -> list:
82
- """Regex search across the repo via git grep (respects .gitignore)."""
83
- argv = ["git", "grep", "-n", "-E", "--", pattern]
84
- if glob:
85
- argv += [glob]
86
- result = run_checked(argv, cwd=self.repo_root, timeout=30)
87
- if not result.ok and not result.stdout:
88
- return []
89
- hits = []
90
- for line in result.stdout.splitlines()[:max_results]:
91
- m = re.match(r"^([^:]+):(\d+):(.*)$", line)
92
- if m:
93
- hits.append({"path": m.group(1), "line": int(m.group(2)),
94
- "text": m.group(3).strip()[:200]})
95
- return hits
96
-
97
- def list_dir(self, rel_path: str = ".") -> list:
98
- target, reason = self._jail(rel_path)
99
- if reason or not target.is_dir():
100
- return []
101
- return sorted(
102
- p.name + ("/" if p.is_dir() else "")
103
- for p in target.iterdir() if p.name != ".git"
104
- )
105
-
106
- def _git_status(self, rel_path: str) -> str:
107
- result = run_checked(
108
- ["git", "status", "--porcelain", "--", rel_path],
109
- cwd=self.repo_root, timeout=10,
110
- )
111
- if result.stdout.strip():
112
- return result.stdout.strip()[:2]
113
- return ""