chasm-cli 1.5.4

Universal chat session manager - harvest, merge, and analyze AI chat history from VS Code, Cursor, and other editors
Documentation
"""Compare the structure of a WORKING session vs the BROKEN Agentic session."""
import json

# Working session (chasm workspace - a small one with edits if possible)
working_path = r'C:\Users\adamm\AppData\Roaming\Code\User\workspaceStorage\82cdabb21413f2ff42168423e82c8bdf\chatSessions\3f5df584-fcdd-47a0-afbf-0695b881f33c.jsonl'
# Broken session
broken_path = r'C:\Users\adamm\AppData\Roaming\Code\User\workspaceStorage\5ec71800c69c79b96b06a37e38537907\chatSessions\6be29cba-331e-4aa4-bc58-659cc20f4800.jsonl'

def analyze_session(label, path, max_requests=2):
    print(f"\n{'='*60}")
    print(f"  {label}: {path.split('\\')[-1]}")
    print(f"{'='*60}")
    with open(path, 'r', encoding='utf-8') as f:
        content = f.read()
    
    lines = content.strip().split('\n')
    print(f"Lines: {len(lines)}, Bytes: {len(content)}")
    
    for i, line in enumerate(lines[:5]):  # only first 5 lines
        obj = json.loads(line)
        kind = obj.get('kind')
        
        if kind == 0:
            v = obj['v']
            print(f"\nLine {i}: kind=0 (initial state)")
            print(f"  Top-level keys: {sorted(v.keys())}")
            print(f"  version: {v.get('version')}")
            print(f"  requests: {len(v.get('requests', []))}")
            
            for j, req in enumerate(v.get('requests', [])[:max_requests]):
                print(f"\n  --- Request {j} ---")
                print(f"  Keys: {sorted(req.keys())}")
                
                # Message format
                msg = req.get('message')
                if isinstance(msg, str):
                    print(f"  message: STRING")
                elif isinstance(msg, dict):
                    print(f"  message: OBJECT, keys={sorted(msg.keys())}")
                    parts = msg.get('parts', [])
                    for k, p in enumerate(parts[:3]):
                        print(f"    Part {k}: {sorted(p.keys())}")
                
                # Response format
                resp = req.get('response', [])
                print(f"  response: {len(resp)} parts")
                for k, rp in enumerate(resp[:8]):
                    rp_kind = rp.get('kind', 'NO_KIND')
                    has_value = 'value' in rp
                    has_uri = 'uri' in rp
                    has_edits = 'edits' in rp
                    print(f"    R{k}: kind={rp_kind}, keys={sorted(rp.keys())}")
                
                # All other fields
                skip = {'message', 'response', 'agent'}
                for key in sorted(req.keys()):
                    if key not in skip:
                        val = req[key]
                        if isinstance(val, (dict, list)):
                            print(f"  {key}: {json.dumps(val)[:120]}")
                        else:
                            print(f"  {key}: {val}")

        elif kind == 1:
            print(f"\nLine {i}: kind=1 (delta), keys={sorted(obj.keys())}")
        elif kind == 2:
            print(f"\nLine {i}: kind=2 (splice), keys={sorted(obj.keys())}")

analyze_session("WORKING (chasm)", working_path, max_requests=1)
analyze_session("BROKEN (Agentic)", broken_path, max_requests=1)

# Also compare with a LIVE session in the working workspace 
# that was created natively (not by chasm-cli)
# Check the model cache to find which sessions are native
import sqlite3
working_db = r'C:\Users\adamm\AppData\Roaming\Code\User\workspaceStorage\82cdabb21413f2ff42168423e82c8bdf\state.vscdb'
conn = sqlite3.connect(working_db)
cur = conn.cursor()
cur.execute("SELECT value FROM ItemTable WHERE key='agentSessions.model.cache'")
row = cur.fetchone()
if row:
    cache = json.loads(row[0])
    print(f"\n\nWorking workspace model cache: {len(cache)} entries")
    for entry in cache[:3]:
        print(f"  resource: {entry.get('resource')}")
        print(f"  label: {entry.get('label')}")
        print(f"  status: {entry.get('status')}")
        print(f"  timing: {entry.get('timing')}")
        print(f"  keys: {sorted(entry.keys())}")
        print()
conn.close()