import * as vscode from 'vscode'; import * as fs from 'fs'; import * as path from 'path'; import { ChatMessage } from '../agent'; import { logInfo, logError } from '../utils'; interface SessionData { taskId: string; history: ChatMessage[]; lastActionStr?: string; timestamp: number; } export class SessionManager { private sessionDir: string; constructor(private context: vscode.ExtensionContext) { // Use globalStorageUri for persistence across workspace restarts this.sessionDir = path.join(this.context.globalStorageUri.fsPath, 'sessions'); this.ensureDir(this.sessionDir); } private ensureDir(dir: string) { if (!fs.existsSync(dir)) { fs.mkdirSync(dir, { recursive: true }); } } /** * Saves the current session state. */ public async saveSession(taskId: string, history: ChatMessage[], lastActionStr?: string) { const sessionData: SessionData = { taskId, history, lastActionStr, timestamp: Date.now() }; const filePath = path.join(this.sessionDir, `session_${this.sanitizeFilename(taskId)}.json`); try { fs.writeFileSync(filePath, JSON.stringify(sessionData, null, 2), 'utf-8'); // Also store the last active taskId in globalState await this.context.globalState.update('activeTaskId', taskId); } catch (error: any) { logError('Failed to save session state', error); } } /** * Loads a specific session by taskId. */ public loadSession(taskId: string): SessionData | null { const filePath = path.join(this.sessionDir, `session_${this.sanitizeFilename(taskId)}.json`); if (!fs.existsSync(filePath)) return null; try { const content = fs.readFileSync(filePath, 'utf-8'); return JSON.parse(content) as SessionData; } catch (error: any) { logError(`Failed to load session for taskId: ${taskId}`, error); return null; } } /** * Loads the last active session. */ public loadLastActiveSession(): SessionData | null { const lastTaskId = this.context.globalState.get('activeTaskId'); if (!lastTaskId) return null; return this.loadSession(lastTaskId); } /** * Clears a specific session. */ public clearSession(taskId: string) { const filePath = path.join(this.sessionDir, `session_${this.sanitizeFilename(taskId)}.json`); if (fs.existsSync(filePath)) { fs.unlinkSync(filePath); } } private sanitizeFilename(name: string): string { return name.replace(/[^a-z0-9]/gi, '_').toLowerCase(); } }