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 all locations where session files might exist, and verify
VS Code's actual file resolution for the session URIs."""
import os, glob, sqlite3, json, base64

WS_BASE = r"C:\Users\adamm\AppData\Roaming\Code\User\workspaceStorage"

# Check both working and broken workspaces
workspaces = {
    "WORKING (chasm)": "82cdabb21413f2ff42168423e82c8bdf",
    "BROKEN (Agentic)": "5ec71800c69c79b96b06a37e38537907",
    "BROKEN (AgenticFortress)": "724ab159cbc91cdd8242d9b5aa690c3b",
}

for label, ws_hash in workspaces.items():
    ws_dir = os.path.join(WS_BASE, ws_hash)
    print(f"\n{'='*70}")
    print(f"{label} ({ws_hash})")
    print(f"{'='*70}")
    
    # 1. List ALL directories in the workspace storage
    print(f"\nDirectories in workspace storage:")
    for item in sorted(os.listdir(ws_dir)):
        full_path = os.path.join(ws_dir, item)
        if os.path.isdir(full_path):
            print(f"  {item}/")
            # Check for chatSessions subdirectories
            for sub in sorted(os.listdir(full_path)):
                sub_path = os.path.join(full_path, sub)
                if os.path.isdir(sub_path):
                    count = len(os.listdir(sub_path))
                    print(f"    {sub}/ ({count} files)")
                elif sub.endswith('.vscdb') or sub.endswith('.json'):
                    size = os.path.getsize(sub_path)
                    print(f"    {sub} ({size:,} bytes)")
        elif item.endswith('.vscdb'):
            size = os.path.getsize(full_path)
            print(f"  {item} ({size:,} bytes)")
    
    # 2. Find ALL .jsonl files recursively
    print(f"\nAll .jsonl files (recursive):")
    for f in glob.glob(os.path.join(ws_dir, "**", "*.jsonl"), recursive=True):
        rel = os.path.relpath(f, ws_dir)
        size = os.path.getsize(f)
        print(f"  {rel} ({size:,} bytes)")
    
    # 3. Find ALL .json files that might be sessions
    print(f"\nAll .json files that might be sessions:")
    for f in glob.glob(os.path.join(ws_dir, "**", "*.json"), recursive=True):
        rel = os.path.relpath(f, ws_dir)
        size = os.path.getsize(f)
        # Skip tiny config files
        base = os.path.basename(f)
        # Check if filename looks like a UUID (session file)
        import re
        if re.match(r'^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.json$', base):
            print(f"  {rel} ({size:,} bytes) ← POSSIBLE SESSION")
        
    # 4. Check if there are multiple state.vscdb files
    print(f"\nAll .vscdb files:")
    for f in glob.glob(os.path.join(ws_dir, "**", "*.vscdb*"), recursive=True):
        rel = os.path.relpath(f, ws_dir)
        size = os.path.getsize(f)
        print(f"  {rel} ({size:,} bytes)")
    
    # 5. Check extension-specific state.vscdb
    ext_db = os.path.join(ws_dir, "GitHub.copilot-chat", "state.vscdb")
    if os.path.exists(ext_db):
        print(f"\n  GitHub.copilot-chat/state.vscdb EXISTS! Checking contents...")
        try:
            conn = sqlite3.connect(f"file:{ext_db}?mode=ro", uri=True)
            rows = conn.execute("SELECT key FROM ItemTable").fetchall()
            print(f"  Keys in extension DB ({len(rows)}):")
            for row in rows:
                val_row = conn.execute("SELECT value FROM ItemTable WHERE key=?", (row[0],)).fetchone()
                val_len = len(val_row[0]) if val_row else 0
                print(f"    {row[0]} ({val_len} chars)")
                # Show chat-related keys
                if 'chat' in row[0].lower() or 'session' in row[0].lower() or 'agent' in row[0].lower():
                    print(f"      VALUE: {val_row[0][:200]}")
            conn.close()
        except Exception as e:
            print(f"  Error reading: {e}")
    
    # 6. Check the chat-session-resources directory
    resources_dir = os.path.join(ws_dir, "GitHub.copilot-chat", "chat-session-resources")
    if os.path.exists(resources_dir):
        count = sum(1 for _ in os.scandir(resources_dir))
        total_size = sum(os.path.getsize(os.path.join(resources_dir, f)) 
                        for f in os.listdir(resources_dir) 
                        if os.path.isfile(os.path.join(resources_dir, f)))
        print(f"\n  chat-session-resources/ exists: {count} items, {total_size:,} bytes total")