vibe-coder-mcp
Version:
Production-ready MCP server with complete agent integration, multi-transport support, and comprehensive development automation tools for AI-assisted workflows.
124 lines (123 loc) • 4.83 kB
JavaScript
import fs from 'fs-extra';
import path from 'path';
import os from 'os';
export class SessionPersistence {
sessionDir;
constructor(sessionDir) {
this.sessionDir = sessionDir || path.join(os.homedir(), '.vibe', 'sessions');
}
async saveSession(sessionId, data) {
try {
await fs.ensureDir(this.sessionDir);
const file = path.join(this.sessionDir, `${sessionId}.json`);
await fs.writeJson(file, {
...data,
lastUpdated: new Date()
}, { spaces: 2 });
}
catch (error) {
throw new Error(`Failed to save session: ${error instanceof Error ? error.message : 'Unknown error'}`);
}
}
async loadSession(sessionId) {
try {
const file = path.join(this.sessionDir, `${sessionId}.json`);
if (await fs.pathExists(file)) {
const data = await fs.readJson(file);
data.startTime = new Date(data.startTime);
data.lastUpdated = new Date(data.lastUpdated);
return data;
}
return null;
}
catch (error) {
throw new Error(`Failed to load session: ${error instanceof Error ? error.message : 'Unknown error'}`);
}
}
async listSessions() {
try {
await fs.ensureDir(this.sessionDir);
const files = await fs.readdir(this.sessionDir);
const sessions = [];
for (const file of files) {
if (file.endsWith('.json')) {
try {
const sessionId = file.replace('.json', '');
const data = await this.loadSession(sessionId);
if (data) {
sessions.push({
id: sessionId,
startTime: data.startTime,
lastUpdated: data.lastUpdated
});
}
}
catch {
}
}
}
sessions.sort((a, b) => b.lastUpdated.getTime() - a.lastUpdated.getTime());
return sessions;
}
catch (error) {
throw new Error(`Failed to list sessions: ${error instanceof Error ? error.message : 'Unknown error'}`);
}
}
async deleteSession(sessionId) {
try {
const file = path.join(this.sessionDir, `${sessionId}.json`);
if (await fs.pathExists(file)) {
await fs.remove(file);
}
}
catch (error) {
throw new Error(`Failed to delete session: ${error instanceof Error ? error.message : 'Unknown error'}`);
}
}
async exportSession(sessionId, outputPath) {
try {
const session = await this.loadSession(sessionId);
if (!session) {
throw new Error('Session not found');
}
let markdown = `# Vibe Interactive Session\n\n`;
markdown += `**Session ID:** ${session.sessionId}\n`;
markdown += `**Started:** ${session.startTime.toLocaleString()}\n`;
markdown += `**Last Updated:** ${session.lastUpdated.toLocaleString()}\n\n`;
markdown += `---\n\n`;
markdown += `## Conversation\n\n`;
session.conversationHistory.forEach((entry, index) => {
const role = entry.role === 'user' ? '👤 You' : '🤖 Vibe';
markdown += `### ${role}\n\n`;
markdown += entry.content + '\n\n';
if (index < session.conversationHistory.length - 1) {
markdown += `---\n\n`;
}
});
const output = outputPath || path.join(process.cwd(), `session-${sessionId}.md`);
await fs.writeFile(output, markdown);
return output;
}
catch (error) {
throw new Error(`Failed to export session: ${error instanceof Error ? error.message : 'Unknown error'}`);
}
}
async cleanOldSessions(daysToKeep = 30) {
try {
const sessions = await this.listSessions();
const cutoffDate = new Date();
cutoffDate.setDate(cutoffDate.getDate() - daysToKeep);
let deleted = 0;
for (const session of sessions) {
if (session.lastUpdated < cutoffDate) {
await this.deleteSession(session.id);
deleted++;
}
}
return deleted;
}
catch (error) {
throw new Error(`Failed to clean sessions: ${error instanceof Error ? error.message : 'Unknown error'}`);
}
}
}