Add plugin helper with agent skill for updating plugins
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
|
||||
def sha256_file(path: Path) -> str:
|
||||
digest = hashlib.sha256()
|
||||
with path.open("rb") as handle:
|
||||
for chunk in iter(lambda: handle.read(1024 * 1024), b""):
|
||||
digest.update(chunk)
|
||||
return digest.hexdigest()
|
||||
|
||||
|
||||
def sha256_bytes(data: bytes) -> str:
|
||||
return hashlib.sha256(data).hexdigest()
|
||||
|
||||
|
||||
def atomic_write_json(path: Path, data: Any) -> None:
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
fd, tmp_name = tempfile.mkstemp(prefix=f".{path.name}.", dir=path.parent)
|
||||
try:
|
||||
with os.fdopen(fd, "w", encoding="utf-8") as handle:
|
||||
json.dump(data, handle, indent=2, sort_keys=True)
|
||||
handle.write("\n")
|
||||
Path(tmp_name).replace(path)
|
||||
except Exception:
|
||||
Path(tmp_name).unlink(missing_ok=True)
|
||||
raise
|
||||
|
||||
|
||||
def read_json(path: Path, default: Any) -> Any:
|
||||
if not path.exists():
|
||||
return default
|
||||
with path.open("r", encoding="utf-8") as handle:
|
||||
return json.load(handle)
|
||||
|
||||
|
||||
def ensure_relative(path: str) -> Path:
|
||||
if "\\" in path:
|
||||
raise ValueError(f"unsafe relative path: {path}")
|
||||
rel = Path(path)
|
||||
if rel.is_absolute() or ".." in rel.parts or any(part.endswith(":") for part in rel.parts):
|
||||
raise ValueError(f"unsafe relative path: {path}")
|
||||
return rel
|
||||
|
||||
|
||||
def ensure_inside(root: Path, target: Path) -> Path:
|
||||
root_resolved = root.resolve()
|
||||
target_resolved = target.resolve(strict=False)
|
||||
try:
|
||||
target_resolved.relative_to(root_resolved)
|
||||
except ValueError as exc:
|
||||
raise ValueError(f"target escapes instance root: {target}") from exc
|
||||
return target_resolved
|
||||
Reference in New Issue
Block a user