89 lines
2.7 KiB
TypeScript
89 lines
2.7 KiB
TypeScript
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<string>('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();
|
|
}
|
|
}
|