#!/usr/bin/env python3 """Self-improvement agent. Reviews recent logs, proposes improvements, applies safe patches.""" import json, re, sys, os from datetime import datetime, timedelta LOG_PATH = "/root/.hermes/logs/self-improvement.log" STATE_PATH = "/root/.hermes/scripts/self-improvement/state.json" TARGETS = [ "/root/sovereign-stack-pwa/README.md", "/root/sovereign-stack-pwa/index.html", "/root/.hermes/skills/", ] def log(msg): with open(LOG_PATH, "a") as f: f.write(f"[{datetime.utcnow().isoformat()}Z] {msg}\n") def load_state(): if os.path.exists(STATE_PATH): return json.load(open(STATE_PATH)) return {"last_run": None, "improvements_applied": 0, "patches_proposed": 0} def save_state(state): json.dump(state, open(STATE_PATH, "w"), indent=2) def review_targets(): """Scan targets for obvious improvement candidates: TODOs, FIXMEs, missing meta tags.""" candidates = [] for target in TARGETS: if os.path.isdir(target): for root, _, files in os.walk(target): for name in files: if name.endswith((".md", ".py", ".html", ".sh", ".json")): candidates.append(os.path.join(root, name)) elif os.path.exists(target): candidates.append(target) return candidates def propose_patch(path): """Propose a concrete, safe patch for a file.""" if not os.path.exists(path): return None with open(path, "r") as f: content = f.read() # Safe improvements only: no rewrites patches = [] if path.endswith(".md") and not content.startswith("#"): patches.append(("prepend-title", f"# {os.path.basename(path)}\n\n")) if "TODO" in content or "FIXME" in content: patches.append(("flag-todos", "\n")) if path.endswith(".html") and '\n')) return patches def apply_patch(path, patches): applied = [] if not patches: return applied with open(path, "r") as f: content = f.read() for kind, snippet in patches: if kind == "prepend-title" and not content.startswith("#"): content = snippet + content applied.append(f"Prepended title to {path}") elif kind == "flag-todos" and "REVIEW_NEEDED" not in content: content = snippet + content applied.append(f"Flagged TODOs in {path}") elif kind == "add-viewport" and '", f"\n {snippet}") applied.append(f"Added viewport meta to {path}") if applied: with open(path, "w") as f: f.write(content) return applied def run(): state = load_state() now = datetime.utcnow() log("Self-improvement run start") candidates = review_targets() total_patches = 0 total_applied = 0 for path in candidates[:20]: # Cap to avoid thrashing patches = propose_patch(path) if patches: state["patches_proposed"] += len(patches) applied = apply_patch(path, patches) if applied: state["improvements_applied"] += len(applied) total_applied += len(applied) for a in applied: log(f"APPLIED: {a}") else: log(f"PROPOSED but not applied: {path}") total_patches += len(patches) state["last_run"] = now.isoformat() + "Z" save_state(state) log(f"Run complete. Patches proposed: {total_patches}, applied: {total_applied}") if __name__ == "__main__": run()