#!/usr/bin/env python3 import glob import json import os import subprocess from datetime import datetime ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..')) SUM_SCRIPT = os.path.join(ROOT, 'scripts', 'ai', 'summarize_chat_session.py') COMPACT_SUM_SCRIPT = os.path.join(ROOT, 'scripts', 'ai', 'summarize_chat_session_compact.py') OUT_REPORT = os.path.join(ROOT, 'docs', 'ai', 'LATEST_2_CHATS_RECOVERY.md') def collect_chat_files(): bases = [os.path.expanduser('~/.config/Code/User/workspaceStorage')] qs = sorted(glob.glob(os.path.expanduser('~/vscode-chat-backups/quarantine-*'))) if qs: bases.append(qs[-1]) items = [] for base in bases: for path in glob.glob(os.path.join(base, '**', 'chatSessions', '*.json'), recursive=True): try: with open(path, 'r', encoding='utf-8', errors='replace') as f: d = json.load(f) ts = d.get('lastMessageDate') or d.get('creationDate') or 0 reqs = len(d.get('requests', [])) if isinstance(d, dict) else 0 if reqs <= 0: continue items.append((ts, reqs, path)) except Exception: continue items.sort(reverse=True, key=lambda x: x[0]) return items def fmt_ts(ts): try: return datetime.fromtimestamp(ts / 1000).strftime('%Y-%m-%d %H:%M:%S') except Exception: return str(ts) def run_summary(chat_file): subprocess.run(['python3', SUM_SCRIPT, '--chat-file', chat_file], check=True) subprocess.run(['python3', COMPACT_SUM_SCRIPT, '--chat-file', chat_file], check=True) def summary_path_for(chat_file): sid = os.path.splitext(os.path.basename(chat_file))[0] return os.path.join(ROOT, 'docs', 'ai', 'chat-summaries', f'{sid}.md') def compact_summary_path_for(chat_file): sid = os.path.splitext(os.path.basename(chat_file))[0] return os.path.join(ROOT, 'docs', 'ai', 'restart', 'compact-summaries', f'{sid}.compact.md') def main(): chats = collect_chat_files()[:2] if len(chats) < 2: raise SystemExit('Non ci sono almeno 2 chat utili da riassumere.') for _, _, chat_file in chats: run_summary(chat_file) os.makedirs(os.path.dirname(OUT_REPORT), exist_ok=True) with open(OUT_REPORT, 'w', encoding='utf-8') as out: out.write('# Latest 2 Chats Recovery\n\n') out.write('Documento auto-generato per ripartenza veloce dopo pulizia chat pesanti.\n\n') for i, (ts, reqs, chat_file) in enumerate(chats, start=1): sid = os.path.splitext(os.path.basename(chat_file))[0] summ = summary_path_for(chat_file) compact = compact_summary_path_for(chat_file) size_mb = os.path.getsize(chat_file) / (1024 * 1024) out.write(f'## Chat {i}\n') out.write(f'- Session ID: {sid}\n') out.write(f'- Last message: {fmt_ts(ts)}\n') out.write(f'- Requests: {reqs}\n') out.write(f'- Size: {size_mb:.1f} MB\n') out.write(f'- Source JSON: {chat_file}\n') out.write(f'- Summary: {os.path.relpath(summ, ROOT)}\n\n') out.write(f'- Compact summary: {os.path.relpath(compact, ROOT)}\n\n') out.write('## Prompt di ripartenza\n') out.write('- Riparti da docs/ai/SESSION_HANDOFF.md, docs/ai/TOPICS_INDEX.md e da questo file; usa prima i compact-summary e continua dal prossimo step senza analisi generale.\n') print(f'Report created: {OUT_REPORT}') if __name__ == '__main__': main()