fix: use UTF-8 for text file operations

This commit is contained in:
Haoran
2026-08-24 20:28:37 +08:00
parent a32a73f700
commit 199402f9d4
59 changed files with 435 additions and 289 deletions

View File

@@ -91,7 +91,7 @@ def run_bash(command: str) -> str:
def run_read(path: str, limit: int = None) -> str:
try:
lines = safe_path(path).read_text().splitlines()
lines = safe_path(path).read_text(encoding="utf-8").splitlines()
if limit and limit < len(lines):
lines = lines[:limit] + [f"... ({len(lines) - limit} more)"]
return "\n".join(lines)[:50000]
@@ -102,7 +102,7 @@ def run_write(path: str, content: str) -> str:
try:
fp = safe_path(path)
fp.parent.mkdir(parents=True, exist_ok=True)
fp.write_text(content)
fp.write_text(content, encoding="utf-8")
return f"Wrote {len(content)} bytes to {path}"
except Exception as e:
return f"Error: {e}"
@@ -110,10 +110,10 @@ def run_write(path: str, content: str) -> str:
def run_edit(path: str, old_text: str, new_text: str) -> str:
try:
fp = safe_path(path)
c = fp.read_text()
c = fp.read_text(encoding="utf-8")
if old_text not in c:
return f"Error: Text not found in {path}"
fp.write_text(c.replace(old_text, new_text, 1))
fp.write_text(c.replace(old_text, new_text, 1), encoding="utf-8")
return f"Edited {path}"
except Exception as e:
return f"Error: {e}"
@@ -201,7 +201,7 @@ class SkillLoader:
self.skills = {}
if skills_dir.exists():
for f in sorted(skills_dir.rglob("SKILL.md")):
text = f.read_text()
text = f.read_text(encoding="utf-8")
match = re.match(r"^---\n(.*?)\n---\n(.*)", text, re.DOTALL)
meta, body = {}, text
if match:
@@ -243,7 +243,7 @@ def microcompact(messages: list):
def auto_compact(messages: list) -> list:
TRANSCRIPT_DIR.mkdir(exist_ok=True)
path = TRANSCRIPT_DIR / f"transcript_{int(time.time())}.jsonl"
with open(path, "w") as f:
with open(path, "w", encoding="utf-8") as f:
for msg in messages:
f.write(json.dumps(msg, default=str) + "\n")
conv_text = json.dumps(messages, default=str)[-80000:]
@@ -270,10 +270,10 @@ class TaskManager:
def _load(self, tid: int) -> dict:
p = TASKS_DIR / f"task_{tid}.json"
if not p.exists(): raise ValueError(f"Task {tid} not found")
return json.loads(p.read_text())
return json.loads(p.read_text(encoding="utf-8"))
def _save(self, task: dict):
(TASKS_DIR / f"task_{task['id']}.json").write_text(json.dumps(task, indent=2))
(TASKS_DIR / f"task_{task['id']}.json").write_text(json.dumps(task, indent=2), encoding="utf-8")
def create(self, subject: str, description: str = "") -> str:
task = {"id": self._next_id(), "subject": subject, "description": description,
@@ -291,7 +291,7 @@ class TaskManager:
task["status"] = status
if status == "completed":
for f in TASKS_DIR.glob("task_*.json"):
t = json.loads(f.read_text())
t = json.loads(f.read_text(encoding="utf-8"))
if tid in t.get("blockedBy", []):
t["blockedBy"].remove(tid)
self._save(t)
@@ -306,7 +306,7 @@ class TaskManager:
return json.dumps(task, indent=2)
def list_all(self) -> str:
tasks = [json.loads(f.read_text()) for f in sorted(TASKS_DIR.glob("task_*.json"))]
tasks = [json.loads(f.read_text(encoding="utf-8")) for f in sorted(TASKS_DIR.glob("task_*.json"))]
if not tasks: return "No tasks."
lines = []
for t in tasks:
@@ -370,15 +370,15 @@ class MessageBus:
msg = {"type": msg_type, "from": sender, "content": content,
"timestamp": time.time()}
if extra: msg.update(extra)
with open(INBOX_DIR / f"{to}.jsonl", "a") as f:
with open(INBOX_DIR / f"{to}.jsonl", "a", encoding="utf-8") as f:
f.write(json.dumps(msg) + "\n")
return f"Sent {msg_type} to {to}"
def read_inbox(self, name: str) -> list:
path = INBOX_DIR / f"{name}.jsonl"
if not path.exists(): return []
msgs = [json.loads(l) for l in path.read_text().strip().splitlines() if l]
path.write_text("")
msgs = [json.loads(l) for l in path.read_text(encoding="utf-8").strip().splitlines() if l]
path.write_text("", encoding="utf-8")
return msgs
def broadcast(self, sender: str, content: str, names: list) -> str:
@@ -407,11 +407,11 @@ class TeammateManager:
def _load(self) -> dict:
if self.config_path.exists():
return json.loads(self.config_path.read_text())
return json.loads(self.config_path.read_text(encoding="utf-8"))
return {"team_name": "default", "members": []}
def _save(self):
self.config_path.write_text(json.dumps(self.config, indent=2))
self.config_path.write_text(json.dumps(self.config, indent=2), encoding="utf-8")
def _find(self, name: str) -> dict:
for m in self.config["members"]:
@@ -509,7 +509,7 @@ class TeammateManager:
break
unclaimed = []
for f in sorted(TASKS_DIR.glob("task_*.json")):
t = json.loads(f.read_text())
t = json.loads(f.read_text(encoding="utf-8"))
if t.get("status") == "pending" and not t.get("owner") and not t.get("blockedBy"):
unclaimed.append(t)
if unclaimed: