#!/usr/bin/env python3 """archive_raw.py — copia meccanica dei trascritti .jsonl di Claude Code prima che il CLI li cancelli (cleanupPeriodDays di default = 30gg, nessun override in settings.json). Nessun parsing, nessun filtro sul contenuto ("as is", deciso 05/09/2026) — pura copia file, idempotente. Design completo/motivazione: archivio/Adrian/progetti/project_archivio_raw_conversazioni.md. Girato via cron (non systemd: e' un batch giornaliero, non un processo reattivo), stesso slot delle 05:xx di collect_logs.py/report.py. """ import platform import shutil from datetime import datetime, timezone from pathlib import Path SOURCE = Path.home() / ".claude" / "projects" # Root Dropbox = tre livelli sopra questo file (script -> archivio-raw-conversazioni -> scripts # -> adrian -> Dropbox). Percorso relativo, non assoluto: stesso identico script gira invariato # su Nave e Ufficio, la cartella "ponte" arriva su entrambe via sync Dropbox (05/09/2026 — # sostituisce il precedente ~/claude-raw-archive locale, mai coperto da backup su Ufficio). DEST_ROOT = Path(__file__).resolve().parents[3] / "claude-raw-archive" LOG = Path(__file__).parent / "archive.log" # Nessuna soglia di eta': e' solo una copia meccanica, non c'e' motivo di lasciare una # finestra scoperta prima del cleanup CLI a 30gg (deciso 05/09/2026 - una sessione ancora # attiva viene semplicemente ricopiata ai run successivi finche' cambia, costo trascurabile). def log(msg: str) -> None: line = f"{datetime.now(timezone.utc).isoformat()} {msg}" print(line, flush=True) with open(LOG, "a") as f: f.write(line + "\n") def already_archived(src: Path, dest: Path) -> bool: if not dest.exists(): return False src_stat = src.stat() dest_stat = dest.stat() return dest_stat.st_size == src_stat.st_size and dest_stat.st_mtime >= src_stat.st_mtime def main() -> None: if not SOURCE.exists(): log(f"sorgente {SOURCE} non trovata, esco") return hostname = platform.node() dest_base = DEST_ROOT / hostname copied = 0 skipped_already = 0 for src_file in SOURCE.rglob("*.jsonl"): rel = src_file.relative_to(SOURCE) dest_file = dest_base / rel if already_archived(src_file, dest_file): skipped_already += 1 continue dest_file.parent.mkdir(parents=True, exist_ok=True) shutil.copy2(src_file, dest_file) copied += 1 log(f"archiviato {rel}") log(f"run completato: {copied} copiati, {skipped_already} gia' presenti") if __name__ == "__main__": main()