chasm-cli 1.5.4

Universal chat session manager - harvest, merge, and analyze AI chat history from VS Code, Cursor, and other editors
Documentation
"""
Inject a known-good test session into the Agentic workspace.
This will tell us whether:
- The workspace can show ANY session (test passes → problem is session content)
- The workspace can't show sessions at all (test fails → problem is workspace config)

Also injects a COPY of a known working session from chasm workspace.
"""
import sqlite3, json, os, uuid, time, base64

WS_BASE = r"C:\Users\adamm\AppData\Roaming\Code\User\workspaceStorage"
AGENTIC_HASH = "5ec71800c69c79b96b06a37e38537907"
WORKING_HASH = "82cdabb21413f2ff42168423e82c8bdf"

agentic_db = os.path.join(WS_BASE, AGENTIC_HASH, "state.vscdb")
agentic_sessions_dir = os.path.join(WS_BASE, AGENTIC_HASH, "chatSessions")

# Generate a new test session ID
test_session_id = str(uuid.uuid4())
now_ms = int(time.time() * 1000)

print(f"Test session ID: {test_session_id}")
print(f"Timestamp: {now_ms}")

# 1. Create a minimal but valid session JSONL file
session_data = {
    "kind": 0,
    "v": {
        "version": 3,
        "sessionId": test_session_id,
        "creationDate": now_ms,
        "initialLocation": "panel",
        "customTitle": "TEST - Injected Session",
        "responderUsername": "GitHub Copilot",
        "hasPendingEdits": False,
        "pendingRequests": [],
        "requests": [
            {
                "requestId": str(uuid.uuid4()),
                "timestamp": now_ms,
                "message": {
                    "text": "Hello, this is a test",
                    "parts": [
                        {"kind": "text", "value": "Hello, this is a test"}
                    ]
                },
                "response": [
                    {
                        "kind": "markdownContent",
                        "content": {
                            "value": "Hello! This is a test response to verify session loading."
                        }
                    }
                ],
                "responseId": str(uuid.uuid4()),
                "modelId": "copilot/gpt-4o",
                "modelState": {
                    "value": 1,
                    "completedAt": now_ms + 1000
                },
                "agent": {"id": ""},
                "codeCitations": [],
                "contentReferences": [],
                "variableData": {
                    "variables": []
                },
                "timeSpentWaiting": 0
            }
        ],
        "inputState": {
            "inputText": "",
            "selections": [],
            "attachments": [],
            "mode": {"id": "agent", "kind": "agent"},
            "contrib": {"chatDynamicVariableModel": []}
        }
    }
}

session_content = json.dumps(session_data, separators=(',', ':'))
session_path = os.path.join(agentic_sessions_dir, f"{test_session_id}.jsonl")

print(f"\nWriting test session to: {session_path}")
os.makedirs(agentic_sessions_dir, exist_ok=True)
with open(session_path, 'w', encoding='utf-8', newline='') as f:
    f.write(session_content)

print(f"Written {os.path.getsize(session_path)} bytes")

# 2. Also copy the working session 44f0cf62 with a new ID
copy_session_id = str(uuid.uuid4())
working_session_path = os.path.join(WS_BASE, WORKING_HASH, "chatSessions", "44f0cf62-331e-43c9-b32c-25d91ebab0b8.jsonl")

with open(working_session_path, 'r', encoding='utf-8') as f:
    working_content = f.read()

# Replace the sessionId in the content
import re
working_content_modified = working_content.replace(
    "44f0cf62-331e-43c9-b32c-25d91ebab0b8",
    copy_session_id
)

# Also change the customTitle so we can identify it
working_content_modified = working_content_modified.replace(
    json.dumps("ChatSessionManager Test Merge") if "ChatSessionManager Test Merge" in working_content_modified else "NOMATCH",
    json.dumps("COPY - Working Session from Chasm")
)

# Check if customTitle was in the working content
if "ChatSessionManager" in working_content:
    print(f"\nReplaced title in copied session")

copy_path = os.path.join(agentic_sessions_dir, f"{copy_session_id}.jsonl")
with open(copy_path, 'w', encoding='utf-8', newline='') as f:
    f.write(working_content_modified)
print(f"Written copy session {copy_session_id} ({os.path.getsize(copy_path)} bytes)")

# 3. Update the index
print(f"\nUpdating index in state.vscdb...")
conn = sqlite3.connect(agentic_db)

# Read current index
row = conn.execute("SELECT value FROM ItemTable WHERE key='chat.ChatSessionStore.index'").fetchone()
if row:
    index = json.loads(row[0])
else:
    index = {"version": 1, "entries": {}}

# Add test session to index
index["entries"][test_session_id] = {
    "sessionId": test_session_id,
    "title": "TEST - Injected Session",
    "lastMessageDate": now_ms,
    "timing": {
        "created": now_ms,
        "lastRequestStarted": now_ms,
        "lastRequestEnded": now_ms + 1000
    },
    "lastResponseState": 1,
    "initialLocation": "panel",
    "isEmpty": False,
    "isImported": False,
    "hasPendingEdits": False,
    "isExternal": False
}

# Add copy session to index
index["entries"][copy_session_id] = {
    "sessionId": copy_session_id,
    "title": "COPY - Working Session from Chasm",
    "lastMessageDate": now_ms,
    "timing": {
        "created": now_ms,
        "lastRequestStarted": now_ms,
        "lastRequestEnded": now_ms
    },
    "lastResponseState": 1,
    "initialLocation": "panel",
    "isEmpty": False,
    "isImported": False,
    "hasPendingEdits": False,
    "isExternal": False
}

conn.execute(
    "INSERT OR REPLACE INTO ItemTable (key, value) VALUES (?, ?)",
    ("chat.ChatSessionStore.index", json.dumps(index))
)

# 4. Update model cache
row = conn.execute("SELECT value FROM ItemTable WHERE key='agentSessions.model.cache'").fetchone()
if row:
    model_cache = json.loads(row[0])
else:
    model_cache = []

# Add test session 
test_b64 = base64.b64encode(test_session_id.encode()).decode().rstrip('=')
model_cache.append({
    "providerType": "local",
    "providerLabel": "Local",
    "resource": f"vscode-chat-session://local/{test_b64}",
    "icon": "vm",
    "label": "TEST - Injected Session",
    "status": 1,
    "timing": {
        "created": now_ms,
        "lastRequestStarted": now_ms,
        "lastRequestEnded": now_ms + 1000
    }
})

# Add copy session
copy_b64 = base64.b64encode(copy_session_id.encode()).decode().rstrip('=')
model_cache.append({
    "providerType": "local",
    "providerLabel": "Local",
    "resource": f"vscode-chat-session://local/{copy_b64}",
    "icon": "vm",
    "label": "COPY - Working Session from Chasm",
    "status": 1,
    "timing": {
        "created": now_ms,
        "lastRequestStarted": now_ms,
        "lastRequestEnded": now_ms
    }
})

conn.execute(
    "INSERT OR REPLACE INTO ItemTable (key, value) VALUES (?, ?)",
    ("agentSessions.model.cache", json.dumps(model_cache))
)

# 5. Update state cache  
row = conn.execute("SELECT value FROM ItemTable WHERE key='agentSessions.state.cache'").fetchone()
if row:
    state_cache = json.loads(row[0])
else:
    state_cache = []

test_resource = f"vscode-chat-session://local/{test_b64}"
copy_resource = f"vscode-chat-session://local/{copy_b64}"

state_cache.append({"resource": test_resource, "read": now_ms})
state_cache.append({"resource": copy_resource, "read": now_ms})

conn.execute(
    "INSERT OR REPLACE INTO ItemTable (key, value) VALUES (?, ?)",
    ("agentSessions.state.cache", json.dumps(state_cache))
)

conn.commit()
conn.close()

print(f"\nDone! Injected 2 test sessions into Agentic workspace:")
print(f"  1. TEST - Injected Session ({test_session_id})")
print(f"  2. COPY - Working Session from Chasm ({copy_session_id})")
print(f"\nIndex now has {len(index['entries'])} entries")
print(f"Model cache now has {len(model_cache)} entries")
print(f"\nPlease:")
print(f"  1. Close this VS Code window")  
print(f"  2. Open the Agentic workspace in VS Code")
print(f"  3. Check Chat History for:")
print(f"     - 'TEST - Injected Session'")
print(f"     - 'COPY - Working Session from Chasm'")
print(f"     - 'Porting VS Code and Copilot Chat to Rust' (recovered session)")