chasm-cli 1.5.4

Universal chat session manager - harvest, merge, and analyze AI chat history from VS Code, Cursor, and other editors
Documentation
"""Check VS Code logs for session loading errors."""
import os, glob, datetime

# VS Code logs location
logs_base = os.path.join(os.environ.get('APPDATA', ''), 'Code', 'logs')

print(f"Looking for logs in: {logs_base}")
print(f"Exists: {os.path.exists(logs_base)}")

if os.path.exists(logs_base):
    # Find the most recent log folder
    log_dirs = sorted(glob.glob(os.path.join(logs_base, "*")), key=os.path.getmtime, reverse=True)
    print(f"\nRecent log directories ({len(log_dirs)} total):")
    for d in log_dirs[:5]:
        mtime = datetime.datetime.fromtimestamp(os.path.getmtime(d))
        print(f"  {os.path.basename(d)} (modified: {mtime})")
    
    # Search for chat/session related errors in recent logs  
    for log_dir in log_dirs[:3]:
        print(f"\n{'='*70}")
        print(f"Searching in: {os.path.basename(log_dir)}")
        print(f"{'='*70}")
        
        # List all log files
        for dirpath, dirnames, filenames in os.walk(log_dir):
            for fname in filenames:
                if fname.endswith('.log'):
                    fpath = os.path.join(dirpath, fname)
                    rel = os.path.relpath(fpath, log_dir)
                    size = os.path.getsize(fpath)
                    
                    # Check if the log contains chat/session related content
                    try:
                        with open(fpath, 'r', encoding='utf-8', errors='ignore') as f:
                            content = f.read()
                        
                        # Search for relevant keywords
                        keywords = ['chatSession', 'session', 'deserialize', 'ChatSessionStore', 
                                    'agentSession', 'copilot-chat', 'chat.ChatSession',
                                    'chatSessions', 'loadSession', 'session failed',
                                    'session error', 'JSONL', 'jsonl']
                        
                        found = []
                        for kw in keywords:
                            if kw.lower() in content.lower():
                                found.append(kw)
                        
                        if found:
                            print(f"\n  {rel} ({size:,} bytes) - MATCHES: {found}")
                            
                            # Find and print lines with matches
                            lines = content.split('\n')
                            for i, line in enumerate(lines):
                                line_lower = line.lower()
                                for kw in found:
                                    if kw.lower() in line_lower and ('error' in line_lower or 'fail' in line_lower or 'warn' in line_lower or 'reject' in line_lower):
                                        # Print context: 1 line before and after
                                        start = max(0, i-1)
                                        end = min(len(lines), i+2)
                                        for j in range(start, end):
                                            marker = ">>>" if j == i else "   "
                                            print(f"            {marker} L{j+1}: {lines[j][:200]}")
                                        print()
                                        break  # Only first match per keyword
                    except:
                        pass

# Also check the main VS Code log
main_log = os.path.join(os.environ.get('APPDATA', ''), 'Code', 'main.log')
if os.path.exists(main_log):
    print(f"\n{'='*70}")
    print(f"Main VS Code log: {main_log}")
    print(f"{'='*70}")
    size = os.path.getsize(main_log)
    print(f"Size: {size:,} bytes")
    
# Check for renderer logs
output_base = os.path.join(os.environ.get('APPDATA', ''), 'Code', 'logs')
for log_dir in log_dirs[:1]:
    # Look for renderer/window logs
    for dirpath, dirnames, filenames in os.walk(log_dir):
        for fname in filenames:
            if 'renderer' in fname.lower() or 'window' in fname.lower() or 'exthost' in fname.lower():
                fpath = os.path.join(dirpath, fname)
                rel = os.path.relpath(fpath, log_dir)
                size = os.path.getsize(fpath)
                print(f"\n  Renderer/Window/ExtHost log: {rel} ({size:,} bytes)")
                
                try:
                    with open(fpath, 'r', encoding='utf-8', errors='ignore') as f:
                        content = f.read()
                    
                    # Find error lines
                    for i, line in enumerate(content.split('\n')):
                        if 'error' in line.lower() and ('chat' in line.lower() or 'session' in line.lower()):
                            print(f"    L{i+1}: {line[:300]}")
                except:
                    pass