import datetime import json from pathlib import Path from pyra.memory import _MEMORY_ROOT from pyra.utils.paths import safe_chmod _INDEX_FILE = _MEMORY_ROOT / "MEMORY_INDEX.md" _JSON_INDEX_FILE = _MEMORY_ROOT / "memory_index.json" _EXCLUDED = {"MEMORY_INDEX.md", "memory_index.json"} def _load_json_index() -> dict: if not _JSON_INDEX_FILE.exists(): return {} try: return json.loads(_JSON_INDEX_FILE.read_text()) except (json.JSONDecodeError, OSError): return {} def update_index() -> None: existing = _load_json_index() files = sorted(_MEMORY_ROOT.rglob("*.md")) files = [f for f in files if f.name not in _EXCLUDED] new_json: dict = {} rows: list[str] = [] for f in files: rel = f.relative_to(_MEMORY_ROOT) rel_key = rel.as_posix() category = rel.parts[0] if len(rel.parts) > 1 else "root" mtime = datetime.datetime.fromtimestamp(f.stat().st_mtime) mtime_str = mtime.strftime("%Y-%m-%d %H:%M") prev = existing.get(rel_key, {}) new_json[rel_key] = { "summary": prev.get("summary", ""), "keywords": prev.get("keywords", []), "modified": mtime.isoformat(timespec="seconds"), } rows.append(f"| {rel} | {category} | {mtime_str} |") _JSON_INDEX_FILE.write_text(json.dumps(new_json, indent=2)) safe_chmod(_JSON_INDEX_FILE, 0o600) table = "\n".join(rows) if rows else "| _(no memory files)_ | — | — |" content = ( "# Memory Index\n\n" "| File | Category | Last Modified |\n" "|------|----------|---------------|\n" f"{table}\n\n" "_Auto-maintained by Pyra. Do not edit manually._\n" ) _INDEX_FILE.write_text(content) safe_chmod(_INDEX_FILE, 0o600) def update_json_entry(rel_path: str, summary: str, keywords: list[str]) -> None: """Update the summary and keywords for one entry in the JSON index.""" index = _load_json_index() entry = index.get(rel_path, {}) entry["summary"] = summary entry["keywords"] = keywords index[rel_path] = entry _JSON_INDEX_FILE.write_text(json.dumps(index, indent=2)) safe_chmod(_JSON_INDEX_FILE, 0o600)